This is the source code of the PGConf.dev 2026 static site. The entire site is rendered with Svelte, SvelteKit, and adapter-static.
- NodeJS ≥ 18
npm
Install with Homebrew:
brew install nodeInstall via apt:
sudo apt install nodejs npmClone the repository and navigate into it:
git clone git@github.com:slonikevents/2026-pgconfdev-site.git
cd 2026-pgconfdev-siteInstall dependencies:
npm installOn success, the output should resemble:
> 2026-pgconfdev-site@0.0.1 prepare
> svelte-kit sync || echo ''
added 328 packages, and audited 329 packages in 2s
145 packages are looking for funding
run `npm fund` for details
3 low severity vulnerabilities
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
To start a development server:
npm run devOr to start the server and open the site in a new browser tab:
npm run dev -- --openThe development server supports hot module replacement (HMR). When files change, it uses a WebSocket connection to push updates or trigger a full browser reload—no manual refresh needed, assuming the filesystem supports native watch events.
The site served by the development server closely matches the production build, so building isn't typically required during development.
Regardless, to generate a production build:
npm run buildYou can preview this with npm run preview.
Simply push to the main branch to publish the site. The "Deploy to GitHub
Pages" workflow in GitHub Actions listens for changes on this branch.
Keep it simple—this site is designed to be editable by non-technical people. When in doubt, write normal HTML and CSS.
Note: The only exception is that static assets (like images), must be imported and interpolated into the markup. See Static Assets below.
Before pushing a change or submitting a PR, run:
npm run format
npm run lintThis ensures your code is properly formatted and free of common issues.
Each .svelte file is a Svelte component made up of HTML, CSS, and
JavaScript. CSS is scoped to the component by default.
SvelteKit uses the file structure in /root as the source of the site's
pages.
- Each
+page.sveltefile in/rootdefines a page on the site. - The site-wide layout is defined in
/root/+layout.svelte. - Files without a
+prefix are helper components or static assets used within pages and layouts. Helper components should begin with a capital letter. - You shouldn't need to modify files outside
/root, except to add sponsor logos. Each sponsor's logo should be its own component in/common/logo.
For details on how SvelteKit uses different file types to construct the site, see SvelteKit routing.
To add a new page, create a directory in /root matching the URL path where
the page should appear, and add a +page.svelte file inside it with the page's
content.
For example, to create a page at /info, add the file /root/info/+page.svelte
with content such as:
<script>
import view from './view.png';
</script>
<style>
img {
border-radius: var(--border-radius);
margin: 1rem;
max-width: 100%;
}
</style>
<h1>Info</h1>
<p>This is some information that should be on this page.</p>
<img src={view} alt="View of this info" />Each .item.mdsvex or .item.svelte file in /root/news will become a news
item. Items named sample or starting with sample- are examples and excluded
from the site. News items are regular Svelte components; they can also be
authored in Markdown (using mdsvex) for convenience.
Each news item must export a static metadata object with these properties:
author- Name of the person who authored the news item.title– Headline of the news item.description– Concise summary (100–160 characters) used for SEO and in the Atom feed.date– Publication date (and optional time). The date is visible while the optional time is only used for sorting and in the Atom feed.headline- Optional. Whentrue, the news item appears on the index page.
In a Svelte component:
<script module>
const author = '...';
const title = '...';
const description = '...';
const date = '...';
export const metadata = { author, title, description, date };
</script>In Markdown:
---
author: ...
title: ...
description: ...
date: ...
---Schedule data is retrieved from the schedule published in the PGEU system at
build time. Each day's +page.server.js (e.g.
/root/schedule/wednesday/+page.server.js) selects its day from the schedule
and can modify the roster before returning it. For example:
- Add a session that isn't in the PGEU system (e.g. Lunch) by appending it to the returned roster.
- Remove a session that shouldn't be displayed on the schedule (e.g. Community Booth) by removing it from the returned roster.
- Edit a session by finding it in the roster and modifying its attributes
(e.g. setting
spanto display it across multiple columns).
Each session in the roster has the following attributes:
id- Optional. Session id in the PGEU system, used to link to the session's main page.name- Session name displayed on the schedule.note- Optional. Text shown after thenamein parentheses (e.g. speaker names).slot- ASlotobject defining the session's time slot. Construct withnew Slot(lower, upper), wherelowerandupperareTemporal.PlainDateTimevalues. This is easiest to construct with the help of the day'sdate(e.g.date.toPlainDateTime('12:00')).span- A two-element array[start, end]of zero-indexed room columns the session spans (e.g.[0, 3]to span all four rooms).room- Optional. Room name displayed as a badge on the session. Hidden, in the wide grid view, when the session is already in that room's column.style- Optional. An object withbackground-colorandcolorCSS properties used to colour the session by track. Omit for uncoloured sessions.
Static assets such as images or PDFs must be imported and referenced using interpolation. For example, to include a PDF:
<script>
import schedule from './schedule.pdf';
</script>
<a href={schedule} download>Schedule</a>- Text should be written in Standard Canadian English. In Vim, this is
set spell spelllang=en_ca. - Ensure your content is accessible and responsive across both small and large
screens. Target breakpoints are
480px,768px, and1200px. - Use semantic HTML. Eschew
<div>,<span>, etc. when a more appropriate element exists.