CodeWorlds
Powrót do kolekcji
Przewodnik13 min czytaniaZespół CodeWorlds

Starlight, motyw dokumentacji dla Astro

Starlight 0.41.7 na licencji MIT dokłada do projektu Astro wyszukiwarkę Pagefind, tłumaczenia i nawigację boczną. Gdzie leży granica skali indeksu.

Starlight, motyw dokumentacji dla Astro

Starlight to integracja dla Astro, która zamienia katalog plików Markdown w stronę dokumentacji z nawigacją boczną, trybem ciemnym, tłumaczeniami i działającą lokalnie wyszukiwarką. Bieżąca wersja pakietu @astrojs/starlight to 0.41.7 z 5 sierpnia 2026 roku, licencja MIT.

Motyw, nie osobny framework

Różnica między motywem a frameworkiem brzmi jak spór o słowa, dopóki nie zaczniesz dopasowywać narzędzia do repozytorium. Docusaurus jest własnym frameworkiem: ma swoje polecenia, swój router, swój cykl budowania. Starlight nie ma nic z tych rzeczy, bo wszystko bierze z Astro. Instalujesz go jako zależność, dopisujesz jedną pozycję do tablicy integrations w astro.config.mjs i dalej pracujesz zwykłym astro dev oraz astro build.

Praktyczny skutek jest taki, że dokumentacja przestaje być osobnym projektem. Strona marketingowa, blog firmowy i dokumentacja mogą siedzieć w jednym repozytorium, dzielić jeden plik konfiguracyjny, jeden zestaw zależności i jeden potok wdrożeniowy. Starlight przejmuje tylko te ścieżki, które sam wstrzykuje, a reszta katalogu src/pages/ należy do Ciebie.

Pakiet dostarcza 25 komponentów, które można podmienić przez pole components w konfiguracji, oraz zestaw komponentów do użycia w treści: Aside, Badge, Card, CardGrid, Icon, Tabs, TabItem, LinkCard, Steps, FileTree, LinkButton i reeksportowany Code z pakietu astro-expressive-code. Kolorowanie składni w blokach kodu robi właśnie Expressive Code, w wersji 0.44.

Odwrotna strona tej zależności jest oczywista i trzeba ją powiedzieć wprost. Zespół, który nie zna Astro, zaczyna od nauki frameworka: kolekcji treści, wysp, adapterów, składni plików .astro. Jeśli w firmie nikt nie dotyka Astro poza dokumentacją, to jest koszt utrzymania wiedzy, której nie da się użyć nigdzie indziej.

Wersja, licencja i numer poniżej jedynki

Licencja jest zgodna we wszystkich trzech miejscach, w których ją sprawdziłem. Plik LICENSE w gałęzi głównej repozytorium withastro/starlight zawiera tekst MIT z prawami autorskimi od 2023 roku. Pole license w rejestrze npm dla wersji 0.41.7 ma wartość MIT. Opublikowana paczka o rozmiarze 336 kilobajtów zawiera 195 plików, w tym package/LICENSE, a także 144 pliki .astro, .ts i .js, czyli realny kod, a nie samą atrapę wskazującą na inny pakiet. To przypadek wzorcowy i nie ma tu nic do rozstrzygania podczas audytu zależności.

Numer wersji jest za to tematem na osobny akapit. Pakiet ukazał się po raz pierwszy jako 0.0.1 w maju 2023 roku i po 186 wydaniach nadal stoi poniżej jedynki, mimo że projekt jest utrzymywany, ma regularny rytm wydań i stoi pod nim zespół Astro. W README pakietu ani w changelogu nie znalazłem zdania deklarującego politykę zgodności, więc jedynym twardym źródłem jest historia zmian. Ta mówi rzecz następującą: spośród 41 wydań mniejszych, od 0.1.0 do 0.41.0, osiemnaście zawiera co najmniej jeden wpis oznaczony jako zmiana łamiąca. Ostatnim przykładem jest 0.41.0, które dodało wsparcie dla Astro 7 i jednocześnie porzuciło Astro 6. Wniosek dla planowania pracy: aktualizacja z 0.40 na 0.41 to nie jest zmiana, którą można przepuścić przez automat aktualizujący zależności bez czytania not wydania.

Zakresy zależności równorzędnych warto sprawdzić razem z tym. Starlight 0.41.7 deklaruje astro w zakresie ^7.0.2 oraz @astrojs/markdown-remark w zakresie ^7.2.0. Bieżące Astro to 7.2.4 z 19 sierpnia 2026 roku, więc oba zakresy są spełnione bez naciągania.

Instalacja i konfiguracja

Dwie ścieżki wejścia: nowy projekt z szablonu albo doinstalowanie do istniejącego.

Code
Bash
# nowy projekt z gotowym szablonem dokumentacji
npm create astro@latest -- --template starlight

# albo dołożenie Starlighta do istniejącego projektu Astro
npx astro add starlight

# praca lokalna i budowanie
npx astro dev
npx astro build

Polecenie astro add starlight instaluje pakiet i dopisuje integrację do konfiguracji, ale kolekcji treści nie utworzy za Ciebie. Trzeba to zrobić ręcznie, w pliku src/content.config.ts, przy użyciu loadera i schematu dostarczanych przez Starlight.

TSsrc/content.config.ts
TypeScript
// src/content.config.ts
import { defineCollection } from 'astro:content'
import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders'
import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'

export const collections = {
  docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }),
  i18n: defineCollection({ loader: i18nLoader(), schema: i18nSchema() })
}

docsLoader czyta pliki z src/content/docs/ o rozszerzeniach md, mdx, markdown, mdown, mkdn, mkd i mdwn, pomijając nazwy zaczynające się od podkreślnika. Jeśli w projekcie jest integracja @astrojs/markdoc, loader dokłada do listy także mdoc. Kolekcja i18n jest opcjonalna i przyjmuje pliki json, yml oraz yaml.

Sama konfiguracja motywu żyje w astro.config.mjs. Poniżej zestaw pól, które faktycznie istnieją w schemacie wersji 0.41.7.

astro.config.mjs
JavaScript
// astro.config.mjs
import { defineConfig } from 'astro/config'
import starlight from '@astrojs/starlight'

export default defineConfig({
  site: 'https://docs.example.com',
  integrations: [
    starlight({
      title: 'Dokumentacja',
      tagline: 'Podręcznik wdrożeniowy',
      titleDelimiter: '|',
      credits: false,
      prerender: true,
      editLink: { baseUrl: 'https://github.com/example/docs/edit/main/' },
      lastUpdated: true,
      pagination: true,
      tableOfContents: { minHeadingLevel: 2, maxHeadingLevel: 3 },
      customCss: ['./src/styles/docs.css'],
      routeMiddleware: './src/starlightRouteData.ts',
      markdown: { headingLinks: true, processedDirs: [] },
      components: {
        Footer: './src/overrides/Footer.astro'
      },
      sidebar: [
        { label: 'Start', link: '/start/' },
        {
          label: 'Przewodniki',
          collapsed: false,
          items: [{ autogenerate: { directory: 'guides', collapsed: true } }]
        }
      ]
    })
  ]
})

Dwa pola z tej listy bywają źródłem cichych błędów. routeMiddleware odrzuci ścieżkę pasującą do ./src/middleware.ts lub ./src/middleware/index.ts, bo te miejsca należą do Astro, i wypisze komunikat z podpowiedzią, żeby plik przemianować. Z kolei w grupach autogenerate nie wolno już podawać pola label: obsługa automatycznie generowanych grup zniknęła w 0.39.0, a schemat zwraca w tym miejscu opisowy błąd z gotową poprawką.

Wyszukiwarka Pagefind i jej realna granica

To jest powód, dla którego w ogóle warto porównywać Starlighta z Docusaurusem. Docusaurus nie ma wyszukiwarki w rdzeniu i kieruje do zewnętrznej usługi Algolia DocSearch, darmowej tylko dla publicznej dokumentacji technicznej i dopiero po zaakceptowanym zgłoszeniu. Starlight ma wyszukiwarkę od pierwszego uruchomienia i nie wymaga żadnej konfiguracji ani konta u kogokolwiek.

Pod spodem siedzi Pagefind w wersji 1.5.2 na licencji MIT, wraz z pakietem @pagefind/default-ui w tej samej wersji. Mechanizm jest prosty: w haku astro:build:done Starlight bierze katalog z gotowym HTML-em, wywołuje createIndex, potem index.addDirectory na katalogu wynikowym, a na końcu index.writeFiles do podkatalogu pagefind/. W logu budowania widać komunikat z liczbą znalezionych plików HTML oraz czas indeksowania.

Z tego mechanizmu wynikają dwa ograniczenia, których nie da się obejść konfiguracją. Pierwsze: indeks powstaje z wygenerowanego HTML-a, więc strony muszą być prerenderowane. Schemat konfiguracji wprost odrzuca kombinację prerender: false z włączonym Pagefind i zwraca komunikat, że wyszukiwanie Pagefind nie jest wspierane przy wyłączonym prerenderowaniu. Drugie: indeksowanie dokłada się do czasu budowania, i to po zakończeniu właściwego budowania, więc na dużej dokumentacji zobaczysz to w potoku wdrożeniowym.

Co do skali, autorzy Pagefinda podają własną miarę: strona o dziesięciu tysiącach podstron ma się przeszukiwać przy całkowitym transferze poniżej 300 kilobajtów łącznie z biblioteką, a dla większości witryn ma to być bliżej 100 kilobajtów. Klucz do tej obietnicy leży w podziale indeksu na fragmenty, z których przeglądarka pobiera tylko te pasujące do zapytania.

Zmierzyłem to na stronie samego Starlighta. Plik pagefind-entry.json waży 1133 bajty i wymienia 17 osobnych indeksów językowych, każdy po 36 stron, czyli 612 stron łącznie. Indeks angielski składa się z trzech plików .pf_index o rozmiarach 20 279, 33 546 i 34 745 bajtów, razem 88 570 bajtów. Do tego dochodzą elementy pobierane zawsze przy pierwszym otwarciu wyszukiwarki: pagefind.js 45 555 bajtów, pagefind-ui.js 119 987 bajtów, pagefind-ui.css 14 482 bajty, wasm.en.pagefind 72 209 bajtów, wspomniany plik wejściowy 1133 bajty i plik metadanych indeksu 450 bajtów. Suma tych sześciu pozycji to 253 816 bajtów. Doliczając jeden fragment indeksu, pierwsze wyszukanie kosztuje od 274 095 do 288 561 bajtów przed kompresją, którą i tak włączy serwer.

Granica skali leży więc w dwóch miejscach naraz. Ponad 250 kilobajtów stałego narzutu to dużo jak na stronę dokumentacji, a odczuwa go każdy, kto kliknie w pole wyszukiwania. Drugie miejsce to wielojęzyczność: Pagefind buduje osobny indeks na każdy język, więc dokumentacja w kilkunastu językach ma kilkanaście indeksów, kilkanaście plików WebAssembly i odpowiednio dłuższe budowanie. Jeśli masz dwieście stron w jednym języku, nie zauważysz problemu. Jeśli masz kilka tysięcy stron w ośmiu językach, policz czas budowania, zanim podejmiesz decyzję.

Zachowanie klienta jest przy tym rozsądne. Kod wyszukiwarki ładuje się dynamicznie przez await import('@pagefind/default-ui') wewnątrz elementu <dialog>, w wywołaniu zaplanowanym przez requestIdleCallback, i tylko w budowaniu produkcyjnym. Konstruktor PagefindUI dostaje element, baseUrl, bundlePath, showImages: false, showSubResults: true oraz tłumaczenia interfejsu.

Trafność wyników da się dostrajać, a nazwy pól odpowiadają jeden do jednego opcjom Pagefinda.

Code
JavaScript
starlight({
  title: 'Dokumentacja',
  pagefind: {
    indexWeight: 1,
    ranking: {
      pageLength: 0.1,
      termFrequency: 0.1,
      termSaturation: 2,
      termSimilarity: 9,
      diacriticSimilarity: 0.8,
      metaWeights: { title: 5 }
    },
    mergeIndex: [
      { bundlePath: 'https://api.example.com/pagefind/', indexWeight: 0.5, language: 'pl' }
    ]
  }
})

Wartości domyślne to dokładnie te podane wyżej, a metaWeights domyślnie waży tytuł piątką. Wyszukiwanie da się też wyłączyć w całości przez pagefind: false, pominąć pojedynczą stronę przez pagefind: false w jej frontmatterze albo wyciąć fragment strony atrybutem data-pagefind-ignore. Kto ma dostęp do programu DocSearch i woli Algolię, może sięgnąć po oficjalną wtyczkę @astrojs/starlight-docsearch w wersji 0.7.0.

Tłumaczenia i nawigacja boczna

Starlight ma tłumaczenia w rdzeniu, bez wtyczek. Pakiet zawiera 34 pliki tłumaczeń interfejsu, od arabskiego po chiński w obu wariantach, i polski jest wśród nich. Konfiguracja sprowadza się do pola locales, w którym klucz root oznacza język serwowany spod głównego adresu, a każdy wpis przyjmuje label, opcjonalny lang oraz dir o wartości ltr lub rtl. Tagi językowe są sprawdzane względem BCP 47, więc literówka w kodzie języka zatrzyma budowanie zamiast wyprodukować martwe adresy.

Code
JavaScript
starlight({
  title: { pl: 'Dokumentacja', en: 'Documentation' },
  defaultLocale: 'root',
  locales: {
    root: { label: 'Polski', lang: 'pl' },
    en: { label: 'English', lang: 'en' },
    ar: { label: 'العربية', lang: 'ar', dir: 'rtl' }
  }
})

Nawigacja boczna działa w dwóch trybach, które można mieszać w jednej tablicy. Pozycja z polem link to zwykły odnośnik i przyjmuje label, translations, badge oraz attrs z atrybutami HTML. Grupa ma label, items i collapsed. Wpis autogenerate czyta katalog i buduje pozycje z plików, przyjmując directory, collapsed i attrs. Kolejność i etykiety pojedynczych stron ustawia się w ich frontmatterze.

Code
Markdown
---
title: Wdrożenie na produkcję
description: Kroki wdrożeniowe i lista kontrolna
template: doc
tableOfContents: false
lastUpdated: 2026-08-10
draft: false
pagefind: true
sidebar:
  label: Wdrożenie
  order: 3
  badge: Nowe
prev: false
next:
  link: /guides/rollback/
  label: Wycofanie zmian
banner:
  content: Ta strona dotyczy wersji 3.x
---

Treść strony w Markdownie.

Pełna lista pól frontmattera to title, description, editUrl, head, tableOfContents, template, hero, lastUpdated, prev, next, sidebar, banner, pagefind i draft. Pole template przyjmuje wartość doc albo splash, przy czym splash jest układem bez nawigacji bocznej, przeznaczonym na stronę tytułową z sekcją hero.

Mieszanie dokumentacji z resztą projektu

Ten punkt jest łatwy do przeoczenia, a bywa decydujący. Skoro Starlight to integracja Astro, to reszta projektu pozostaje zwykłym projektem Astro. Strona główna, cennik, blog i formularz kontaktowy leżą w src/pages/, dokumentacja w src/content/docs/, a jedno budowanie produkuje wszystko naraz.

Code
TEXT
src/
  content.config.ts
  content/
    docs/            # przejmuje Starlight
      index.mdx
      guides/
    i18n/            # tłumaczenia interfejsu
  pages/
    index.astro      # strona marketingowa, poza Starlightem
    pricing.astro
  components/
    PricingTable.tsx # wyspa [React] albo dowolny inny framework
  styles/
    docs.css

Komponenty interaktywne pisane w Reakcie działają na stronie marketingowej jako wyspy i można je osadzić także w treści MDX dokumentacji. Bundlerem jest Vite, typy sprawdza TypeScript, a jeśli w projekcie stoi Tailwind CSS w wersji 4, to oficjalna wtyczka @astrojs/starlight-tailwind w wersji 5.0.0 dopasowuje motyw dokumentacji do tej samej palety. Rozwiązanie hostowane takiej możliwości nie da z definicji, bo dokumentacja żyje wtedy poza Twoim repozytorium.

Starlight wobec Docusaurusa, Mintlify i Nextry

CechaStarlight 0.41.7Docusaurus 3.10.2MintlifyNextra 4.6.1
Podstawaintegracja Astrowłasny framework na Reakcieplatforma hostowanamotyw dla Next.js
Wyszukiwarka w rdzeniutak, Pagefind lokalnienie, zewnętrzna Algoliatak, po stronie dostawcytak, lokalna
Wersjonowanie w rdzeniunie, wtyczka społecznościowataktak, po stronie dostawcynie
Blog w rdzeniunie, wtyczka społecznościowatak, w presecie classictak, po stronie dostawcynie
Tłumaczenia w rdzeniutak, 34 języki interfejsutaktak, po stronie dostawcytak
LicencjaMITMITElastic 2.0, silnik zamkniętyMIT
Ostatnie wydanie5 sierpnia 202610 lipca 2026narzędzie mint 22 sierpnia 20264 grudnia 2025

Najważniejsza różnica wobec Docusaurusa to brak wersjonowania dokumentacji w rdzeniu Starlighta. Kto utrzymuje kilka wersji głównych produktu równolegle, dostaje w Docusaurusie gotowy mechanizm katalogów versioned_docs, a w Starlighcie musi sięgnąć po wtyczkę starlight-versions. To projekt utrzymywany przez jedną osobę spoza zespołu Astro, w wersji 0.10.0 z 21 sierpnia 2026 roku, na licencji MIT. Podobnie z blogiem: starlight-blog w wersji 0.29.0 pochodzi z tego samego źródła. Oficjalne, sygnowane przez @astrojs wtyczki są trzy: starlight-docsearch, starlight-tailwind i starlight-markdoc. Wszystko poza nimi utrzymuje społeczność, ze wszystkim, co z tego wynika przy dłuższej perspektywie utrzymania.

Wobec Mintlify różnica jest innego rodzaju: tam płacisz i dostajesz gotową platformę z zamkniętym silnikiem, tu masz kod na MIT we własnym repozytorium i sam odpowiadasz za hosting. Nextra pozostaje sensownym wyborem dla zespołu już siedzącego w Next.js, ale jej ostatnie wydanie pochodzi z grudnia 2025 roku, więc rytm prac jest wyraźnie wolniejszy niż w dwóch pozostałych projektach.

Typowe błędy

Pierwszy: brak pliku src/content.config.ts. Polecenie astro add starlight dokłada integrację, ale kolekcji nie utworzy, a bez docsLoader strona nie znajdzie żadnych treści.

Drugi: prerender: false przy włączonej wyszukiwarce. Konfiguracja zostanie odrzucona z komunikatem o braku wsparcia dla Pagefinda bez prerenderowania. Jeśli fragment strony musi działać po stronie serwera, wyłącz prerenderowanie tylko dla tej trasy, a nie globalnie.

Trzeci: pole label wewnątrz obiektu autogenerate. Ten zapis przestał działać w 0.39.0. Trzeba utworzyć grupę z etykietą, a wpis autogenerate umieścić w jej tablicy items.

Czwarty: plik middleware nazwany src/middleware.ts i podany w routeMiddleware. Ta ścieżka koliduje z mechanizmem Astro, więc schemat zwraca błąd. Nazwij plik inaczej, na przykład src/starlightRouteData.ts.

Piąty: aktualizacja wydania mniejszego bez czytania not. Osiemnaście z czterdziestu jeden wydań mniejszych zawierało zmianę łamiącą, więc automat podbijający zależności potrafi zepsuć budowanie.

Szósty: zakresy zależności równorzędnych we wtyczkach są otwarte od góry. starlight-blog deklaruje >=0.41.0, starlight-versions deklaruje >=0.39.0, a starlight-tailwind >=0.38.0. Menedżer pakietów nie zatrzyma instalacji wtyczki na wersji Starlighta nowszej, niż ta wtyczka była testowana.

FAQ

Czy Starlight nadaje się do dużej dokumentacji?

Do kilkuset stron w jednym języku bez zastrzeżeń. Powyżej tego progu sprawdź dwie rzeczy: czas indeksowania Pagefindem, doliczany po zakończeniu budowania, oraz liczbę języków, bo każdy dostaje osobny indeks i osobny plik WebAssembly. Autorzy Pagefinda deklarują poprawne działanie przy dziesięciu tysiącach stron i transferze poniżej 300 kilobajtów.

Czy da się wersjonować dokumentację?

Nie w rdzeniu. Służy do tego wtyczka starlight-versions, utrzymywana poza zespołem Astro, w wersji 0.10.0 na licencji MIT. Jeśli wersjonowanie jest wymogiem twardym, Docusaurus ma je w rdzeniu i to jest realny argument za nim.

Co oznacza numer wersji poniżej jedynki?

Że wydania mniejsze mogą łamać zgodność, i w tym projekcie faktycznie ją łamały: osiemnaście z czterdziestu jeden wydań mniejszych ma w changelogu wpis oznaczony jako zmiana łamiąca. Przykład z ostatnich miesięcy to 0.41.0, które porzuciło wsparcie dla Astro 6.

Czy trzeba znać Astro, żeby użyć Starlighta?

Do postawienia strony z szablonu nie. Do zmiany układu, podmiany któregokolwiek z 25 komponentów albo dołożenia własnych stron tak, bo pracujesz wtedy w plikach .astro i w kolekcjach treści Astro.

Jak wyłączyć indeksowanie wybranej strony?

Wpisz pagefind: false w jej frontmatterze. Żeby wyciąć fragment strony, opakuj go elementem z atrybutem data-pagefind-ignore. Całą wyszukiwarkę wyłącza pagefind: false w konfiguracji integracji.

Czy dokumentacja może stać obok strony marketingowej?

Tak, i to jest jedna z głównych zalet tego rozwiązania. Starlight obsługuje kolekcję docs, a katalog src/pages/ zostaje do Twojej dyspozycji. Jedno repozytorium, jedno budowanie, jedno wdrożenie.

Źródła: dokumentacja Starlighta, dokumentacja Pagefinda oraz plik licencyjny w repozytorium.

Czytaj dalej

Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie