The source for lokiwager.app, built with Astro.
This repository is the publishing site for the blog and long-form engineering series, including the GPU runtime tutorial work that lives alongside the code repos. It is not a generic theme repo anymore; it is the actual content and site implementation for Loki's Wager.
- Astro 6
- Tailwind CSS
- Markdown content collections
- MDX support
- Shiki code highlighting
- Satori-generated OG images
- RSS and sitemap generation
- Pagefind static search
- optional webmentions integration
- Node.js
20.19.1+or22.12.0+ pnpm8.x
Install dependencies:
pnpm installStart the local dev server:
pnpm devUseful commands:
| Command | Purpose |
|---|---|
pnpm dev |
Start the local Astro dev server |
pnpm build |
Build the site into dist/ and run Pagefind after the build |
pnpm preview |
Preview the production build locally |
pnpm check |
Run Astro type/content checks |
pnpm lint |
Run ESLint |
pnpm format |
Format the repo with Prettier |
pnpm format:check |
Check formatting without rewriting files |
The resume source lives in:
resume/resume.yml
It is generated automatically during local development and production builds:
pnpm devtriggerspredev, which generatespublic/resume-preview/resume.htmlpnpm buildtriggersprebuild, which generates the same HTML before Astro builds the site
CI deployment only needs the normal site build:
pnpm build
Posts live in:
src/content/post/
The content schema is defined in:
src/content.config.ts
Each post is a Markdown file with frontmatter. The important fields are:
titledescriptionpublishDateupdatedDatetagscoverImageogImagedraft
Notes:
titleis limited to 60 charactersdescriptionmust stay between 50 and 160 characters- tags are normalized to lowercase and deduplicated
- draft posts are excluded from the production build
To add a new post:
- Create a new file in
src/content/post/. - Add frontmatter that satisfies the content schema.
- Write the article in Markdown.
- Run
pnpm buildbefore publishing so the content collection, generated pages, OG images, RSS, sitemap, and Pagefind index all stay in sync.
If a post needs a generated social image, the OG image route is here:
src/pages/og-image/[slug].png.ts
If a post should use a custom social image instead, set ogImage in frontmatter.
The main site metadata lives in:
src/site.config.ts
That file controls:
- site title
- author
- description
- locale
- date formatting
- giscus comments integration
- webmention endpoint
- header and footer menu links
The Astro-level site configuration lives in:
astro.config.ts
That file controls:
- canonical site URL
- Markdown plugins
- Tailwind integration
- sitemap generation
- image handling
- Vite behavior
src/pages/for route definitionssrc/layouts/for shared page layoutssrc/components/for reusable UI piecessrc/styles/global.cssfor global stylespublic/for static assetsdist/for build output
This site uses build-time search indexing with Pagefind.
That means:
pnpm buildproduces the Astro site- the
postbuildscript then indexes searchable content fromdist/
RSS and sitemap generation are handled automatically during the Astro build.
The site includes webmention components, but the build can still succeed without a webmention token in local development.
If you want webmentions enabled in a deployed environment, make sure the endpoint in src/site.config.ts and any required environment configuration are set correctly.
The blog can embed GitHub Discussions comments through giscus.
Setup checklist:
- Enable GitHub Discussions for the repository you want to use for comments.
- Install/configure the giscus app for that repository and pick a discussion category.
- Optionally override the defaults in
.env.exampleif you want to use a different repository or category.
Current defaults are already wired to this repository:
PUBLIC_GISCUS_REPOPUBLIC_GISCUS_REPO_IDPUBLIC_GISCUS_CATEGORYPUBLIC_GISCUS_CATEGORY_ID
Defaults already match the current post URL structure:
PUBLIC_GISCUS_MAPPING=pathnamePUBLIC_GISCUS_INPUT_POSITION=topPUBLIC_GISCUS_THEME_LIGHT=lightPUBLIC_GISCUS_THEME_DARK=dark_dimmed
If you switch to PUBLIC_GISCUS_MAPPING=specific or PUBLIC_GISCUS_MAPPING=number, also set PUBLIC_GISCUS_TERM.
The production domain is:
lokiwager.app
Relevant deployment files:
netlify.tomlpublic/CNAME
The current Netlify build command is:
pnpm build