Skip to content

Astro Starlight Installation and One-Shot Codex Setup Request

Section titled “Astro Starlight Installation and One-Shot Codex Setup Request”

Build an Astro Starlight knowledge base that can be maintained primarily by adding Markdown files.

Target architecture:

  • Astro Starlight
  • Markdown / MDX
  • Japanese site under /ja/
  • English site under /en/
  • Independent Japanese and English sidebars
  • Pagefind with language-specific search
  • Sidebar generated automatically from the directory tree
  • Directory index pages using index.mdx + DirectoryIndex.astro
  • Configurable directory listing depth using depth={N} or recursive
  • Preprocessing of imported Markdown to add missing title frontmatter
  • GitHub-managed source and content
  • Static deployment such as Cloudflare Pages
  • Native Windows development
  • No requirement for WSL or Docker

You can use the native Windows version of Node.js,
but use nvm-windows if you need to switch between multiple versions.

Verify that Node.js and npm are available.

ターミナルウィンドウ
winget search nvm
winget install CoreyButler.NVMforWindows
# In a separate terminal
nvm version
nvm --version
nvm install 22
nvm use 22
where.exe node
where.exe npm

Move to the working directory.

Example:

ターミナルウィンドウ
cd "P:\git"

Create an Astro project from the Starlight template:

ターミナルウィンドウ
npm create astro@latest -- --template starlight

Example answers:

Where should we create your new project?
./markdown-site
Install dependencies?
Yes
Initialize a new git repository?
Yes

Development server:

ターミナルウィンドウ
npm run dev

Production build:

ターミナルウィンドウ
npm run build

Preview the production build:

ターミナルウィンドウ
npm run preview

Astro checks:

ターミナルウィンドウ
npx astro check

3. One-Shot Codex Request After Installation

Section titled “3. One-Shot Codex Request After Installation”

Give the following request to Codex once so that all behavior discussed previously is implemented from the beginning.


Configure this Astro Starlight project as a Japanese/English knowledge base that can be maintained primarily by adding Markdown files.

The most important requirement is:

For normal content updates, adding a Markdown file should automatically update the sidebar, directory listing, and search index.

Avoid unnecessary large custom implementations. Prefer Astro and Starlight standard features, and add small overrides only where necessary.


Static site generator:

Astro Starlight

Content:

Markdown / MDX

Languages:

/ja/ Japanese
/en/ English

The Japanese and English sites are not required to be exact mirrors.

They may have different:

  • content trees
  • categories
  • sidebars

Use the following as the base:

src/
├── components/
│ ├── DirectoryIndex.astro
│ ├── Sidebar.astro
│ ├── SidebarTree.astro
│ └── supporting components as needed
│
├── styles/
│ └── custom.css
│
├── content/
│ └── docs/
│ ├── ja/
│ │ ├── index.mdx
│ │ ├── tech/
│ │ │ ├── index.mdx
│ │ │ ├── aws/
│ │ │ │ ├── index.mdx
│ │ │ │ ├── control-tower.md
│ │ │ │ └── organizations.md
│ │ │ └── terraform/
│ │ │ ├── index.mdx
│ │ │ └── state.md
│ │ └── english/
│ │ └── index.mdx
│ │
│ └── en/
│ ├── index.mdx
│ └── tech/
│ ├── index.mdx
│ └── aws/
│ ├── index.mdx
│ └── control-tower.md
│
├── content.config.ts
└── ...
scripts/
└── normalize-content.mjs
astro.config.mjs
package.json
README.md

Adjust as needed to match current Starlight best practices.


Use:

*.md

for normal articles.

Use:

index.mdx

for category or directory index pages.

Example:

aws/
├── index.mdx
├── control-tower.md
├── organizations.md
└── vpc.md

Avoid unnecessary custom components in normal articles.


Use Starlight locales.

Conceptually:

locales: {
ja: {
label: '日本語',
lang: 'ja',
},
en: {
label: 'English',
lang: 'en',
},
}

Ensure:

/ja/ → <html lang="ja">
/en/ → <html lang="en">

Locales must remain enabled because Pagefind uses them for language-specific search.


The Japanese and English sites are not complete mirrors, so do not show the top-right Japanese/English language switcher.

Keep:

locales → enabled
HTML lang → enabled
Pagefind → enabled
LanguageSelect UI → hidden

Use a Starlight component override or other supported mechanism.

Do not hide it later with fragile CSS or DOM manipulation.


6. Completely separate Japanese and English sidebars

Section titled “6. Completely separate Japanese and English sidebars”

Generate the Japanese sidebar only from:

src/content/docs/ja/

Generate the English sidebar only from:

src/content/docs/en/

Example Japanese structure:

Technology
AWS
Terraform
English Learning
Health
Investment

Example English structure:

Technology
AWS
Cloud Security
Finance

A Japanese-only directory such as:

/ja/english/

must not appear in the English sidebar.

Do not require adding every page manually to astro.config.mjs.


7. Generate the sidebar from the filesystem

Section titled “7. Generate the sidebar from the filesystem”

For example, adding:

src/content/docs/ja/tech/aws/vpc.md

must automatically add the page under AWS in the Japanese sidebar.

Adding:

src/content/docs/ja/tech/kubernetes/
├── index.mdx
└── networking.md

must automatically add the Kubernetes group.


For:

aws/
├── index.mdx
├── control-tower.md
└── organizations.md

render:

▼ AWS
Control Tower
Organizations

Do not show index.mdx as a duplicate child entry.

Clicking the AWS label should navigate to:

/ja/tech/aws/

and simultaneously leave the AWS tree expanded.

Use the disclosure icon to expand/collapse the tree.


For:

backup/
├── backup-3-2-1-rule.md
└── another.md

do not make backup a navigation link.

Expected:

▶ backup

Clicking backup must:

  • not navigate
  • keep the current page unchanged
  • never produce a 404
  • only expand/collapse the backup tree

Automatically determine whether each directory has a corresponding index.mdx.


9. Expand sidebar ancestors based on the current URL

Section titled “9. Expand sidebar ancestors based on the current URL”

The current page and its ancestor directories should be expanded automatically.

Example:

/ja/tech/

should show:

▼ Technology
▶ AWS
▶ Terraform

Example:

/ja/tech/aws/

should show:

▼ Technology
▼ AWS
Control Tower
Organizations
▶ Terraform

Example:

/ja/tech/aws/control-tower/

should still show:

▼ Technology
▼ AWS
Control Tower
Organizations

Only Control Tower should be active; ancestors should be open but not active.

Prefer URL-based state so this also works for:

  • direct URLs
  • bookmarks
  • reload
  • back/forward
  • Pagefind search results

10. Always show the sidebar on /ja/ and /en/

Section titled “10. Always show the sidebar on /ja/ and /en/”

Use the normal Starlight page layout for locale home pages.

The sidebar must be visible on:

/ja/
/en/

Do not use:

template: splash

for these pages.

Category landing pages should also normally use the standard layout.


This is a knowledge base, not a linear tutorial.

Disable the page-bottom Previous / Next navigation using the supported Starlight setting.

Example:

pagination: false

Keep the desktop right-hand TOC.

However, hide the automatic Starlight page-top Overview entry so it does not duplicate an actual Markdown heading such as:

## Overview

or:

## 概要

Expected Japanese TOC:

目次
概要
なぜ必要か
「2」の意味

Do not show:

概要
概要

Remove the Starlight structural overview entry, not a text string named “概要”.

Do not use fragile CSS or DOM post-processing.

Apply the same behavior in English.


Category index.mdx pages should be simple.

Example:

---
title: AWS
description: AWS articles.
---
import DirectoryIndex from '.../DirectoryIndex.astro';
<DirectoryIndex />

If practical, simplify the component import path.

DirectoryIndex should automatically determine the current directory and render matching pages.


Support:

<DirectoryIndex />

or:

<DirectoryIndex depth={1} />

→ direct children only

<DirectoryIndex depth={2} />

→ up to two levels below

<DirectoryIndex depth={3} />

→ up to three levels below

<DirectoryIndex recursive />

→ all descendants

If both recursive and depth are supplied, recursive wins.

Keep <DirectoryIndex /> backward-compatible as depth 1.


Requirements:

  • exclude the current index.mdx
  • automatically collect Markdown / MDX pages
  • sort by sidebar.order when present
  • otherwise sort by title
  • render description
  • optionally render lastUpdated
  • optionally render tags

Handle subdirectory category pages in a way that is consistent with the navigation model.


16. Render DirectoryIndex as a list, not cards

Section titled “16. Render DirectoryIndex as a list, not cards”

Do not use cards.

Use a simple list such as:

AWS Control Tower
Introduction to AWS Control Tower.
AWS Organizations
Introduction to AWS Organizations and OUs.
IAM Identity Center
Introduction to IAM Identity Center.

Requirements:

  • no card background
  • no border box
  • no border radius
  • title is a link
  • description below title
  • reasonable spacing or a subtle separator
  • visually consistent with Starlight
  • dark-mode compatible

17. Do not manually maintain section/category frontmatter

Section titled “17. Do not manually maintain section/category frontmatter”

Derive classification from the directory path.

Example:

src/content/docs/ja/tech/aws/control-tower.md

should internally map to:

language = ja
section = tech
category = aws

Example:

src/content/docs/en/finance/trading/risk.md

should map to:

language = en
section = finance
category = trading

For shallower paths, undefined values are acceptable.

Do not require:

section:
category:

in every Markdown file.

Avoid duplicated metadata between directory structure and frontmatter.

If Pagefind filters need these values later, derive them from the path.


Base article:

---
title: AWS Control Tower
description: Introduction to AWS Control Tower.
---

Optional:

sidebar: { order: 10 }

or:

tags:
- AWS

Keep Astro/Starlight-specific metadata to a minimum.


Add a preprocessing command:

ターミナルウィンドウ
npm run normalize-content

Target:

src/content/docs/**/*.md
src/content/docs/**/*.mdx

When title is missing, determine it in this order:

1. existing frontmatter title
2. first H1
3. first H2
4. filename without extension

20. Use frontmatter title and body H1 together

Section titled “20. Use frontmatter title and body H1 together”

Input:

# Backup 3-2-1 Rule
## Overview

Normalized output:

---
title: Backup 3-2-1 Rule
---
# Backup 3-2-1 Rule
## Overview

Treat title as metadata for the sidebar, listings, and SEO, and the body H1 as the visible page heading.

Use a component override to suppress Starlight’s automatically rendered frontmatter PageTitle. This avoids duplicate titles while preserving the body H1 in imported Markdown.

Style the body H1 to resemble Starlight’s former PageTitle:

  • add a subtle 1px underline spanning the full content-column width
  • leave appropriate space between the H1 and its underline
  • do not add a custom underline to H2; retain Starlight’s default H2 styling

Use these rules:

frontmatter title exists
→ do not change body H1
no title + H1
→ promote H1 to title and keep that H1 in the body
no title + no H1 + H2
→ use H2 as title but keep the H2
no H1/H2
→ use filename

The normalizer must:

  • process .md and .mdx
  • include index.mdx
  • skip files with an existing title
  • preserve existing frontmatter
  • avoid modifying metadata other than title
  • ignore headings inside fenced code blocks
  • ignore text inside frontmatter
  • preserve UTF-8 Japanese text
  • preserve CRLF/LF where practical
  • preserve BOM where practical
  • be idempotent
  • produce no unnecessary diff on the second run

Support:

ターミナルウィンドウ
npm run normalize-content -- --dry-run

Example:

Would update:
- src/content/docs/ja/tech/backup/backup-3-2-1-rule.md
title: バックアップの「3-2-1ルール」メモ
source: H1
preserve source H1: yes
1 file would be updated.

Add:

{
"scripts": {
"normalize-content": "node scripts/normalize-content.mjs"
}
}

Adjust the script filename if needed.

Avoid unnecessary dependencies.

A lightweight standard YAML/frontmatter library may be used if it improves correctness and maintainability.


Use Starlight’s Pagefind search.

Do not use an external search service.

Japanese:

/ja/

should search Japanese content only.

English:

/en/

should search English content only.

Use correct HTML lang values and Pagefind multilingual indexing.


The design should support future filters such as:

Entire site
Technology
AWS
Terraform
Kubernetes

No filter UI is required now.

Make it possible to derive:

language
section
category

from the path.


Allow images near their related content.

Example:

aws/
├── control-tower.md
└── images/
├── control-tower.drawio
├── control-tower.svg
└── control-tower-console.webp

Convention:

*.drawio → editable source
*.svg → web version of diagrams
*.webp → screenshots
*.png → when needed

Markdown should be able to reference them with relative paths.

Use an appropriate shared asset location for site-wide images.


Do not remove the Astro Dev Toolbar merely because it appears during npm run dev.

It is a development-only tool and normally does not appear in the production build.


Document:

ターミナルウィンドウ
npm install
npm run dev
ターミナルウィンドウ
npm run build
ターミナルウィンドウ
npm run preview
ターミナルウィンドウ
npm run normalize-content
ターミナルウィンドウ
npm run normalize-content -- --dry-run

Example:

src/content/docs/ja/tech/aws/vpc.md

Minimum frontmatter:

---
title: VPC
description: Introduction to VPC.
---

Copy Markdown files into src/content/docs/, then run:

ターミナルウィンドウ
npm run normalize-content

Example:

src/content/docs/ja/tech/kubernetes/
├── index.mdx
└── networking.md

Document:

<DirectoryIndex />
<DirectoryIndex depth={2} />
<DirectoryIndex depth={3} />
<DirectoryIndex recursive />

Explain that it behaves as a collapsible sidebar group and does not navigate.


Provide enough sample content to test at least:

Japanese:

/ja/
/ja/tech/
/ja/tech/aws/
/ja/tech/aws/control-tower/
/ja/tech/terraform/
/ja/english/

English:

/en/
/en/tech/
/en/tech/aws/
/en/tech/aws/control-tower/

Also test at least one directory without index.mdx.


Verify all of the following:

  1. sidebar appears on /ja/ and /en/
  2. Japanese and English sidebars are independent
  3. LanguageSelect is hidden
  4. Pagefind searches only the current language
  5. directory with index.mdx is a link
  6. clicking it navigates and expands the tree
  7. index.mdx does not appear as a duplicate sidebar child
  8. directory without index.mdx only expands/collapses and never 404s
  9. deep direct URLs expand all sidebar ancestors
  10. DirectoryIndex uses list layout
  11. depth={1,2,3} works
  12. recursive includes all descendants
  13. Previous / Next navigation is hidden
  14. right-side TOC remains visible
  15. automatic Starlight Overview does not duplicate Markdown ## Overview / ## 概要
  16. normalize-content adds missing titles
  17. H1 remains in the body when promoted to title
  18. a second normalize run produces no diff
  19. no manual section/category metadata is required
  20. adding Markdown automatically updates sidebar, listing, and search

Run:

ターミナルウィンドウ
npm run normalize-content
npm run build

If available, also run:

ターミナルウィンドウ
npx astro check

Then run:

ターミナルウィンドウ
npm run normalize-content

again to confirm idempotency.


Report:

  1. files added/changed
  2. final directory structure
  3. Japanese/English sidebar separation
  4. sidebar auto-generation logic
  5. behavior for directories with/without index.mdx
  6. current/ancestor auto-expansion logic
  7. DirectoryIndex depth/recursive implementation
  8. DirectoryIndex sorting
  9. Pagefind language separation
  10. LanguageSelect override
  11. pagination disabling
  12. TOC overview de-duplication
  13. normalize-content title logic
  14. H1 preservation and idempotency
  15. path-derived section/category logic
  16. README updates
  17. npm run build / astro check results
  18. exact workflow for adding future Markdown content

Avoid unnecessary refactoring and keep the implementation easy to maintain across future Starlight upgrades.