Skip to content

Website Setup

This page is autogenerated, just as a note to myself of how I made/use this website.

This page is autogenerated, just as a note to myself of how I made/use this website.

Frontmatter (example)

---
title: "My site stack: Astro + Starlight + Obsidian"
description: "How I write in Obsidian and publish with Astro/Starlight on GitLab Pages."
pubDatetime: 2025-10-03
published: true
tags: [astro, starlight, obsidian, gitlab-pages]
---
  • Write notes in src/content/docs/** (this folder is my Obsidian vault).

  • Starlight renders docs (sidebar, search, MDX components).

  • GitLab Pages deploys to /personal-website/.

  • Dev commands at the bottom.

Search works only in production builds (npm run preview or on Pages).


Search works only in production builds (npm run preview or on Pages).

  • Astro (site), Starlight (docs UI).

  • Obsidian vault at src/content/ (ignore .obsidian in git).

  • Plugins in build:

    • remark-obsidian-comments → strips %% … %%.

    • remark-obsidian-embeds → turns ![[…]] image embeds into <img>.

    • remark-gfm, remark-math + rehype-katex.

    • remark-wiki-link for [[Note]] links between pages.

src/
assets/ # images used in layouts/hero
content/
docs/
index.mdx # home (splash + CardGrid)
books/** # autogenerate
articles/** # autogenerate
rabbits/** # autogenerate
lib/markdown/
remark-obsidian-embeds.mjs
remark-obsidian-comments.mjs
styles/
katex.css
  • Files & Links → New link format: Relative path

  • Files & Links → Default location for new attachments: “In subfolder next to current file” (e.g., attachments/)

  • Core “Markdown format converter” only if I want to convert wikilinks to standard Markdown for a note.

import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
import remarkGfm from 'remark-gfm';
import remarkMath from 'remark-math';
import remarkWikiLink from 'remark-wiki-link';
import rehypeKatex from 'rehype-katex';
import remarkObsidianEmbeds from './src/lib/markdown/remark-obsidian-embeds.mjs';
import remarkObsidianComments from './src/lib/markdown/remark-obsidian-comments.mjs';
export default defineConfig({
site: 'https://popoiopo.gitlab.io',
base: '/personal-website',
integrations: [starlight({
title: 'My Website',
customCss: ['./src/styles/katex.css', './src/styles/callouts.css'],
sidebar: [
{ label: 'Books', autogenerate: { directory: 'books' } },
{ label: 'Articles', autogenerate: { directory: 'articles' } },
{ label: 'Rabbit holes', autogenerate: { directory: 'rabbits' } },
],
})],
markdown: {
remarkPlugins: [
remarkObsidianComments,
remarkGfm,
remarkMath,
remarkObsidianEmbeds, // converts ![[...]] images -> <img>
[remarkWikiLink, { // links between pages
pageResolver: name => {
const hasExt = /\.[a-z0-9]+$/i.test(name);
return [hasExt ? name : name.replace(/\s+/g, '-').toLowerCase()];
},
hrefTemplate: perm => `/${perm}/`,
aliasDivider: '|',
}],
],
rehypePlugins: [rehypeKatex],
},
});

src/styles/katex.css

@import 'katex/dist/katex.min.css';

(If you styled callouts) src/styles/callouts.css with .markdown-alert* rules.

src/content/docs/index.mdx

---
title: "Welcome! 🥳"
template: splash
hero:
tagline: "My name is Bas Châtel"
image:
file: ../../assets/BasChatel.png
actions:
- text: "Articles"
link: /articles/
icon: edit
- text: "Books"
link: /books/
icon: book
- text: "Rabbit holes"
link: /rabbits/
icon: sparkles
---
import { Card, CardGrid } from '@astrojs/starlight/components';
<CardGrid stagger>
<Card title="Start with Articles" icon="edit" href="/articles/">Notes & essays.</Card>
<Card title="Books" icon="book" href="/books/">Reading notes.</Card>
<Card title="Rabbit holes" icon="sparkles" href="/rabbits/">Deep dives.</Card>
</CardGrid>
  • Keep attachments relative to the note:

    src/content/docs/articles/my-post.md
    src/content/docs/articles/attachments/pasted-image-2025.png
  • Embed (Obsidian style) — the embed plugin handles encoding:

    ![[attachments/pasted-image-2025.png]]
  • Prefer kebab-case filenames.

> [!note]
> This renders as a styled callout.
Inline: $E = mc^2$
Block:
$$
\int_0^1 x^2\,dx = \tfrac{1}{3}
$$
Terminal window
# local dev server (no search index, base ignored)
npm run dev
# production build (generates Pagefind search, respects base)
npm run build
# serve the production build locally (search works)
npm run preview

.gitlab-ci.yml

image: node:20
cache:
paths: [node_modules/]
pages:
script:
- npm ci
- npm run build
- mv dist public
artifacts:
paths: [public]
only: [main]

Important

  • Project name must match base in astro.config.mjs:

    • Repo personal-websitebase: '/personal-website'.
  • In dev, link with /articles/...; in production the base is auto-prefixed.

  • Search missing in dev: expected; use npm run preview.

  • 404 on links like /.src/...: you linked a filesystem path—use route paths (/articles/first-post/).

  • Images not rendering: ensure file is relative to the note; avoid spaces; restart after config changes.

  • Excalidraw data shown: wrapped in %% … %% and removed by the comments plugin.