Development
Tech Docs is a Node.js application, built with Astro and its Starlight documentation site framework. The source code is hosted on GitHub. The site is statically built and (temporarily) hosted via Cloudflare Pages. Content is written in Markdown. When the source code changes, a new set of static files are generated and published shortly after.
Dependencies
Section titled “Dependencies”Tech Docs depends on the following open source software (see .nvmrc and package.json for versions):
- Node.js - JavaScript development and build environment; the version noted in
.nvmrcreflects the default version of Node.js in the Cloudflare Pages build image - Astro - Static site generator conceptually based on “components” (React, Vue, Svelte, etc.) rather than “templates” (Jekyll, Handlebars, Pug, etc.)
- Cypress - End-to-end testing framework
- Stylelint - CSS linter used locally in text editors and remotely in CI for testing
- stylelint-config-recommended - Base set of lint rules
- postcss-html - PostCSS syntax for parsing HTML (and HTML-like including .astro files)
- stylelint-config-html - Allows Stylelint to parse .astro files
- Prettier - Source code formatter used locally in text editors and remotely in CI for testing
- prettier-plugin-astro - Allows Prettier to parse .astro files via the command line
Local development
Section titled “Local development”Run Tech Docs locally by cloning the Tech Docs repository, installing project dependencies, and spinning up a development server:
# Requires git and Node.js
# Clone Tech Docs and move to itgit clone https://github.com/archivesspace/tech-docs.gitcd tech-docs
# Install dependenciesnpm install
# Run dev servernpm startNow go to localhost:4321 to see Tech Docs running locally. Changes to the source code will be immediately reflected in the browser.
Building the site
Section titled “Building the site”Building the site creates a set of static files, found in dist after build, that can be served locally or deployed to a server. Sometimes building the site surfaces errors not found in the development environment.
# Build the site and output it to dist/npm run buildAvailable npm scripts
Section titled “Available npm scripts”The following scripts are made available via package.json. Invoke any script on the command line from the project root by prepending it with the npm run command, ie: npm run start.
start— run Astro dev serverbuild— build Tech Docs for productionpreview— serve the static buildastro— get Astro helptest:dev— run tests in development modetest:prod— run tests in production modetest— defaults to run tests in production modeprettier:check— check formatting with Prettierprettier:fix— fix possible format errors with Prettierstylelint:check— lint CSS with Stylelintstylelint:fix— fix possible CSS lint errors with Stylelint
Search
Section titled “Search”Site search is a Starlight feature:
By default, Starlight sites include full-text search powered by Pagefind, which is a fast and low-bandwidth search tool for static sites.
No configuration is required to enable search. Build and deploy your site, then use the search bar in the site header to find content.
YAML frontmatter and content schemas
Section titled “YAML frontmatter and content schemas”Frontmatter for both documentation pages and blog posts is validated at build time through src/content.config.ts. For copy-paste templates and a short description of each field authors should set, see YAML frontmatter. The sections below cover the full Starlight field set for docs, what is required versus optional, and how blog metadata is rendered in the UI.
Documentation pages
Section titled “Documentation pages”Documentation pages use Starlight’s frontmatter schema extended with issueUrl and issueText in src/content.config.ts. Starlight requires a title; other keys are optional unless your page has a specific need.
| Field | Required | Purpose |
|---|---|---|
title | Yes | Page title in the layout, browser tab, and metadata. |
description | No | Short summary for SEO, search, and social previews. Most pages set this; it is omitted on a few pages (for example Staff interface, 404). |
slug | No | Overrides the URL segment instead of deriving it from the file path. |
editUrl | No | Overrides the “Edit page” URL, or false to hide the link (for example on 404). |
head | No | Extra tags for the document head (meta, link, custom title, etc.). |
tableOfContents | No | Table of contents: false to hide, or { minHeadingLevel, maxHeadingLevel } to tune range. |
template | No | Starlight layout template (for example splash). |
hero | No | Hero area for splash-style pages (title, tagline, optional image, actions, etc.). |
banner | No | Optional banner above the page content. |
lastUpdated | No | Override the displayed last-updated date, or false to hide it. |
prev | No | Previous pagination link: false, a string label, or { link, label }. |
next | No | Next pagination link: false, a string label, or { link, label }. For example, Development sets this so “next” goes to Home instead of the external Help Center entry after it in the sidebar. |
pagefind | No | Set false to omit the page from the Pagefind index. |
draft | No | When true, exclude the page from production builds. |
sidebar | No | Per-page sidebar label, order, badge, hidden, or link attrs. The main sidebar structure is configured in src/siteNavigation.json. |
issueUrl | No | URL for the footer “report an issue” link, or false to hide it. Defaults in src/content.config.ts when omitted; authors may set explicitly (see YAML frontmatter). |
issueText | No | Label text for that footer link. Defaults in src/content.config.ts when omitted; authors may set explicitly (see YAML frontmatter). |
Blog posts
Section titled “Blog posts”The blog collection uses a Zod schema defined in src/content.config.ts.
| Field | Required | Purpose |
|---|---|---|
title | Yes | Post headline on the post page and index card. May include HTML for display; the document <title> and prev/next pagination labels strip HTML from title. |
metaDescription | Yes | Short summary for page meta description (SEO). Used as the index teaser text when teaser is omitted. |
teaser | No | HTML or plain text for the blog index card (set:html). Prefer this for links or light HTML on the index; plain text in title is safest where tab titles and pagination matter. |
pubDate | Yes | Publication date; posts are sorted by this field, newest first. Parsed from frontmatter and formatted for display in UTC on the index and post header. |
authors | Yes | Array of author display names; shown comma-separated on the index and post page. |
updatedDate | No | Optional revision date (YYYY-MM-DD). Stored in frontmatter but not shown in the UI today; useful for future display or consistency with the authoring template. |
The blog is implemented as an Astro content collection alongside the docs collection. Post source files are in src/content/blog/; routes live under src/pages/blog/. There is no separate blog build step—blog pages are part of the normal Astro static output, and site search (Search) indexes them like other HTML. For where to put files and example frontmatter, see Authoring content and YAML frontmatter. For schema, validation, and HTML behavior, see YAML frontmatter and content schemas above.
Blog content collection
Section titled “Blog content collection”The blog collection is registered in src/content.config.ts with a Zod schema. Adding or renaming frontmatter fields requires updating that schema and every consumer of entry.data (blog pages, middleware, and tests).
Blog routes
Section titled “Blog routes”src/pages/blog/index.astro—/blogindex; loads posts, sorts bypubDatedescending, passes data to the index UI.src/pages/blog/[id].astro— individual posts;getStaticPathscomes from the collection, so new valid posts appear on the next build.
Blog route middleware
Section titled “Blog route middleware”src/blogRouteData.js is Starlight route middleware for blog routes. It injects pubDate, authors, and postTitle for post pages and sets prev/next pagination (older post as “Previous,” newer as “Next”). Pagination labels use titles with HTML stripped.
Blog UI components
Section titled “Blog UI components”| Area | Location |
|---|---|
| Index list and cards | src/components/BlogIndex.astro |
| Index page title | src/components/BlogIndexTitleHeader.astro |
| Post title, date, authors, back link | src/components/BlogPostTitleHeader.astro, src/components/BackToBlog.astro |
| Default vs blog title | src/components/CustomPageTitle.astro |
| Header “Blog” link | src/components/overrides/Header.astro |
| Blog layout / sidebar behavior | src/components/overrides/PageFrame.astro |
Blog tests
Section titled “Blog tests”End-to-end coverage is in cypress/e2e/blog.cy.js. Update these tests when you change blog markup, URLs, or visible behavior.
Theme customization
Section titled “Theme customization”Starlight can be customized in various ways, including:
- Settings — see
astro.config.mjs - CSS — see
src/styles/custom.css - Components — see
src/components
Static assets
Section titled “Static assets”Images
Section titled “Images”Most image files should be stored in src/images. This allows for processing by Astro which includes performance optimizations.
Images that should not be processed by Astro, like favicons, should be stored in public.
The public directory
Section titled “The public directory”Files placed in public are not processed by Astro. They are copied directly to the output and made available from the root of the site, so public/favicon.svg becomes available at docs.archivesspace.org/favicon.svg, while public/example/slides.pdf becomes available at docs.archivesspace.org/example/slides.pdf.
Update npm dependencies
Section titled “Update npm dependencies”Run the following commands locally to update the npm dependencies, then push the changes upstream.
# List outdated dependenciesnpm outdated
# Update dependenciesnpm updateImport aliases
Section titled “Import aliases”Astro supports import aliases which provide shortcuts to writing long relative import paths.
---import relativeA from '../../images/A_logo.svg' // no aliasimport aliasA from '@images/A_logo.svg' // alias---Sitemap
Section titled “Sitemap”Starlight has built-in sitemap support which is enabled via the top-level site key in astro.config.mjs. This key generates /sitemap-index.xml and /sitemap-0.xml when Tech Docs is built, and adds the sitemap link to the <head> of every page. public/robots.txt also points to the sitemap.
Testing
Section titled “Testing”End-to-end
Section titled “End-to-end”Tech Docs uses Cypress for end-to-end testing customizations made to the underlying Starlight framework and other project needs. End-to-end tests are located in cypress/e2e.
Run the Cypress tests locally by first building and serving the site:
# Build the sitenpm run build
# Serve the build outputnpm run previewThen in a different terminal initiate the tests:
# Run the testsnpm testCode style
Section titled “Code style”Nearly all files in the Tech Docs code base get formatted by Prettier to ensure consistent readability and syntax. Run Prettier locally to find format errors and automatically fix them when possible:
# Check formatting of .md, .css, .astro, .js, .yml, etc. filesnpm run prettier:check
# Fix any errors that can be overwritten automaticallynpm run prettier:fixAll CSS in .css and .astro files are linted by Stylelint to help avoid errors and enforce conventions. Run Stylelint locally to find lint errors and automatically fix them when possible:
# Check all CSSnpm run stylelint:check
# Fix any errors that can be overwritten automaticallynpm run stylelint:fixBefore new changes are accepted into the code base, the end-to-end and code style tests need to pass. Tech Docs uses GitHub Actions for its continuous integration and continuous delivery (CI/CD) platform, which automates the testing and deployment processes. The tests are defined in yaml files found in .github/workflows/ and are run automatically when new changes are proposed.