Skip to content

Astro + Starlight from Zero: A Complete Beginner's Guide

Version: 15 September 2026

Astro gives you the web framework. Starlight gives you the documentation experience. Markdown gives you a simple way to write the content.

This guide shows how those pieces fit together so you can build a documentation-style knowledge site with a left sidebar, a main article area, a right-side On this page navigation, search, dark/light mode, and multiple languages.

If you want a deeper explanation of Astro pages, routing, components, layouts, and content collections first, read Astro from Zero.

The goal is a site with the same broad information architecture used by many developer documentation sites:

┌─────────────────┬───────────────────────────────┬──────────────────┐
│ Left Sidebar │ Main Article │ On this page │
│ │ │ │
│ Astro │ Astro + Starlight from Zero │ Prerequisites │
│ ├ Astro from │ │ Structure │
│ │ Zero │ Article content... │ Frontmatter │
│ └ Astro + │ │ Build │
│ Starlight │ ## Section │ │
└─────────────────┴───────────────────────────────┴──────────────────┘

Starlight provides most of this without requiring us to manually build a documentation shell.

A first version of the site can stay small:

HarryLo.com
└── Astro
├── Astro from Zero
└── Astro + Starlight from Zero

Later it can grow naturally:

HarryLo.com
├── Astro
├── Home Lab ← future
└── MarketLens ← future

Those future sections are examples only. Do not create placeholder pages before there is real content.

Astro is the web framework underneath the site:

Astro
Web framework

Astro handles things such as building the site, routing, components, integrations, and static HTML generation.

Starlight is built on Astro and is designed specifically for documentation-style sites:

Astro
Starlight
Documentation experience

Starlight adds the ready-made documentation layer: sidebar navigation, page structure, search, responsive UI, theme switching, internationalization, and more.

If you want to understand Astro itself in more depth, including file-based routing and dynamic routes such as [slug].astro and [...slug].astro, read Astro from Zero.

You can build a documentation site with plain Astro, but then you may need to maintain your own:

  • sidebar;
  • language switcher;
  • search interface;
  • table of contents;
  • article layout;
  • mobile navigation;
  • theme switcher;
  • previous/next links.

Starlight already provides the common documentation features.

If you add:

astro/
├── astro-from-zero.md
└── astro-starlight-from-zero.md

Starlight can generate navigation from those files.

If your article contains:

## Installation
## Configuration
### Languages
### Sidebar
## Build

Starlight can build the right-side page outline automatically.

Starlight includes full-text search based on Pagefind by default for static sites.

Dark and light theme support is already part of the Starlight experience.

Starlight supports multiple locale directories, which works well for matching English and Traditional Chinese pages.

Code fences such as:

```js
const message = 'Hello Astro';
```

can be rendered with syntax highlighting.

The useful rule is:

Use built-in Starlight behaviour first
Customize only when there is a real requirement

A plain Astro documentation implementation might look conceptually like this:

Markdown
Content Collection
[...slug].astro
getStaticPaths()
Layout
Page

With Starlight, the normal documentation flow is simpler:

Markdown
src/content/docs/
Starlight
Sidebar + TOC + Search + Page

Starlight does not replace Astro. It runs on top of Astro.

For a deeper explanation of the plain Astro routing model, see Astro from Zero.

Before creating an Astro project, check your environment.

Run:

Terminal window
node -v

At the time this guide was written, current Astro documentation requires Node.js 22.12.0 or later and does not support odd-numbered Node releases such as Node 23.

For an existing project, also check whether it contains:

.nvmrc

or Node requirements in:

package.json

Project-specific requirements should normally take priority when working in that repository.

Check npm:

Terminal window
npm -v

npm installs packages and runs project scripts.

Check Git:

Terminal window
git --version

Git is strongly recommended so you can review and recover source-code changes safely.

For a brand-new site, the official Starlight starter is the easiest approach:

Terminal window
npm create astro@latest -- --template starlight

The command can be understood as:

npm
Use the Node package manager
create astro@latest
Run the current Astro project creator
-- --template starlight
Use the Starlight starter

If you want to inspect the current CLI options instead of relying on an old tutorial, run:

Terminal window
npx create-astro@latest --help

npx can run the package-provided CLI without requiring you to install Astro globally.

For examples in this guide, imagine the new project is called:

my-blog

Then:

Terminal window
cd my-blog

Inside the project folder:

Terminal window
npm run dev

Astro normally starts a local development server, often at:

http://localhost:4321/

While the development server is running:

Edit source file
Astro detects the change
Browser updates

Use development mode while writing. Production build and preview are separate steps.

A simplified Starlight project may look like this:

my-blog/
├── public/
├── src/
│ ├── content/
│ │ └── docs/
│ ├── pages/
│ └── content.config.ts
├── astro.config.mjs
├── package.json
├── tsconfig.json
├── .nvmrc
└── README.md

Static files served as-is, for example:

public/
├── favicon.svg
└── images/

This is the key folder for normal Starlight articles.

For example:

src/content/docs/
└── en/
└── astro/
└── astro-from-zero.md

This is Astro’s normal file-based routing area.

Normal Starlight documentation articles do not need their own route files here.

This site can use:

src/pages/index.astro

for a special root redirect:

/
/en/

That is separate from normal Starlight docs routing.

Configures the content collection used by Starlight.

The main Astro configuration file, including the Starlight integration and Starlight options.

Contains dependencies and npm scripts such as:

npm run dev
npm run build
npm run preview

If present, records the expected Node version for the project.

Usually contains developer-facing instructions for working with the repository.

A current Starlight docs collection can be configured like this:

import { defineCollection } from 'astro:content';
import { docsLoader } from '@astrojs/starlight/loaders';
import { docsSchema } from '@astrojs/starlight/schema';
export const collections = {
docs: defineCollection({
loader: docsLoader(),
schema: docsSchema(),
}),
};

Creates a structured Astro content collection.

Loads Starlight documentation content.

src/content/docs/
docsLoader()
docs collection

Provides Starlight’s frontmatter schema and validation.

A beginner project normally does not need to extend the schema immediately.

A minimal Astro + Starlight config can look like:

import { defineConfig } from 'astro/config';
import starlight from '@astrojs/starlight';
export default defineConfig({
site: 'https://example.com',
integrations: [
starlight({
title: 'My Site',
}),
],
});

Defines the production site URL.

Registers Astro integrations. Starlight is one of them.

Sets the site title used by Starlight.

This site’s Astro section can use:

sidebar: [
{
label: 'Astro',
items: [
{
autogenerate: {
directory: 'astro',
},
},
],
},
]

The important part is:

autogenerate: {
directory: 'astro',
}

That tells Starlight to generate sidebar entries from the astro documentation directory.

A locale configuration can look conceptually like this:

defaultLocale: 'en',
locales: {
en: {
label: 'English',
lang: 'en',
},
zh: {
label: '繁體中文',
lang: 'zh-Hant',
},
}

The keys match content directories:

src/content/docs/en/
src/content/docs/zh/

So these matching source files:

src/content/docs/en/astro/example.md
src/content/docs/zh/astro/example.md

can become matching routes:

/en/astro/example/
/zh/astro/example/

Starlight does not automatically translate your article.

Each language version is its own authored Markdown file.

For the current Astro section:

src/content/docs/
├── en/
│ ├── index.md
│ └── astro/
│ ├── astro-from-zero.md
│ └── astro-starlight-from-zero.md
└── zh/
├── index.md
└── astro/
├── astro-from-zero.md
└── astro-starlight-from-zero.md

A useful mental model is:

Folder structure
Content organisation
URL structure

For example:

src/content/docs/en/astro/astro-starlight-from-zero.md

maps conceptually to:

/en/astro/astro-starlight-from-zero/

A small Starlight page:

---
title: My First Page
description: My first Starlight page.
---
This is my introduction.
## First Section
Hello Starlight.

The section between the --- markers is frontmatter.

Everything after it is the Markdown article body.

A practical example:

---
title: "Astro Routing"
description: "Learn Astro file-based routing."
sidebar:
label: "Routing"
order: 3
---

The full page title.

A short description of the page.

Lets the sidebar use a shorter label than the page title.

Controls ordering inside an autogenerated sidebar group.

For example:

order: 1
Astro from Zero
order: 2
Astro + Starlight from Zero

15. Why You Normally Do Not Add Another H1

Section titled “15. Why You Normally Do Not Add Another H1”

If frontmatter contains:

title: "Astro Routing"

Starlight already renders the main page title.

If the Markdown body also begins:

# Astro Routing

you may get a duplicated title.

A cleaner pattern is:

---
title: "Astro Routing"
---
Introductory text.
## First Section
...

Think of it as:

Frontmatter title
Page title
## headings
Article sections

Imagine:

astro/
├── astro-from-zero.md
├── astro-starlight-from-zero.md
├── routing.md
└── content-collections.md

The sidebar can appear approximately as:

Astro
├── Astro from Zero
├── Astro + Starlight from Zero
├── Routing
└── Content Collections

routing.md and content-collections.md are examples only.

The normal workflow is:

Create Markdown
+
Add frontmatter
+
Existing autogeneration
Sidebar entry appears

You normally do not need to edit astro.config.mjs every time you add an article to an already autogenerated section.

Markdown headings such as:

## Installation
## Configuration
### Languages
### Sidebar
## Build

can produce:

On this page
Installation
Configuration
Languages
Sidebar
Build

That is why a Starlight article normally does not need a manually written:

## Table of Contents

or manual anchors such as:

<a id="configuration"></a>

Use clean ## and ### headings and let Starlight generate the page navigation.

Once the site is configured, the workflow should be simple.

Example:

Astro Routing
src/content/docs/en/astro/routing.md

Step 3: Create the matching Chinese Markdown

Section titled “Step 3: Create the matching Chinese Markdown”
src/content/docs/zh/astro/routing.md

These are examples only.

---
title: "Astro Routing"
description: "Understand routing in Astro."
sidebar:
label: "Routing"
order: 3
---
Introduction.
## File-based Routing
...
## Static Routes
...
## Dynamic Routes
...
Terminal window
npm run dev
Terminal window
npm run build
npm run preview

The important point is what you normally do not need:

No new [...slug].astro
No new article layout
No custom sidebar component
No custom TOC

For a simple static image:

public/
└── images/
└── astro/
└── project-structure.png

Use:

![Astro project structure](/images/astro/project-structure.png)

Files under public/ are served from the site root.

A simple mental model is:

public/
Static files served as-is
src/assets/
Assets managed through Astro's source pipeline

For a beginner documentation page, public/images/ is often the easiest starting point.

```js
export const hello = 'world';
```
```ts
const title: string = 'Astro + Starlight';
```
```bash
npm run dev
```
```json
{
"name": "my-blog"
}
```
```yaml
title: My Page
description: My description
```

The language identifier after the opening backticks controls syntax highlighting.

A visitor may open:

https://harrylo.com/

while the English documentation lives under:

/en/

A small Astro page:

src/pages/index.astro

can handle:

/
/en/

This is a special-purpose Astro route.

Normal Starlight content still lives in:

src/content/docs/

So:

src/pages/index.astro
Root redirect
src/content/docs/
Documentation content
Command Purpose
npm run dev Run the development server while editing
npm run build Create the production build
npm run preview Preview the production version locally
Terminal window
npm run dev
Terminal window
npm run build

Conceptually:

Markdown + source
Astro + Starlight build
dist/

dist/ is generated output. Do not manually edit it.

Run the project’s real preview script:

Terminal window
npm run preview

Always inspect package.json to see exactly what the script does.

A project may define:

{
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro build && astro preview"
}
}

In that case:

npm run preview
Build
Start preview server

Use Ctrl + C to stop the server.

Starlight provides Pagefind-based full-text search by default for static sites.

The production index is created during the build process:

Markdown content
Production build
Pagefind index
Starlight search

That means the safest way to verify final search behaviour is with the production build/preview workflow.

After adding an article, check whether searching for its title finds the new page.

Starlight already provides theme support.

A first version does not need a custom component such as:

DarkModeToggle.astro

Use the built-in behaviour unless you later have a specific design requirement.

Matching paths make bilingual maintenance easier:

/en/astro/astro-starlight-from-zero/
/zh/astro/astro-starlight-from-zero/

and:

src/content/docs/en/astro/astro-starlight-from-zero.md
src/content/docs/zh/astro/astro-starlight-from-zero.md

The structure is:

Same topic
Same relative path
Different locale
Different authored content

Language switching is not automatic translation.

Keep deployment separate from content authoring.

The general static-site flow is:

Markdown + source
npm run build
dist/
Hosting platform

Astro + Starlight build the site. The hosting platform serves it.

For a beginner tutorial, it is enough to understand this separation before learning provider-specific deployment configuration.

Later, the site can expand:

HarryLo.com
├── Astro
│ ├── Astro from Zero
│ ├── Astro + Starlight from Zero
│ ├── Routing
│ └── Content Collections
├── Home Lab ← future
│ ├── Network
│ ├── Firewall
│ ├── Proxmox
│ └── NAS
└── MarketLens ← future

The future names above are examples only.

A useful depth guideline is:

Level 1 = major topic
Level 2 = category
Level 3 = article or smaller category
Level 4 = only when genuinely useful

Avoid unnecessary nesting. Let the hierarchy grow when real content justifies it.

If frontmatter already contains title, do not normally repeat the same title as a Markdown # heading.

Do not add a manual Table of Contents when On this page already provides it.

Normal Markdown headings are usually enough.

The source path affects content organization and the route.

Prefer matching relative paths for the same topic.

Use:

sidebar:
order: 2

when the position matters.

Check .nvmrc, package.json, and current Astro requirements.

After cloning/copying a project, dependencies may need to be installed.

Edit source files, not generated build output.

Starlight handles locale structure, not automatic article translation.

If Starlight already provides sidebar, TOC, search, or theme support, use the built-in feature first.

Confusing development with production verification

Section titled “Confusing development with production verification”

Use npm run dev for authoring and build/preview for final production checks.

Editing astro.config.mjs for every article

Section titled “Editing astro.config.mjs for every article”

An existing autogenerated section should not normally need a config change for each new Markdown file.

The normal content workflow is:

Write Markdown
Place it in src/content/docs/
Starlight reads it
Astro builds it
Sidebar + Article + TOC + Search
Static website

For most technical articles, your main work should be:

Markdown
+
Frontmatter
+
Images/code examples

You should not normally need new routing, layout, sidebar, or TOC code for every article.

Useful future topics include:

  • Astro Routing;
  • Content Collections;
  • MDX;
  • Starlight customization;
  • image handling;
  • deployment.

Do not create empty pages just to make the sidebar larger. Add topics when you have real content.

For Astro fundamentals behind the site, use Astro from Zero as the companion guide.

Astro, Starlight, and Markdown each have a different role:

Astro
Provides the web framework
Starlight
Provides the documentation experience
Markdown
Provides the article content

The normal workflow becomes:

Create Markdown
Write frontmatter
Write the tutorial
npm run dev
npm run build / preview
Publish

Once this workflow is working, the site can grow from two Astro tutorials into a much larger knowledge base without changing the basic mental model.