Install and configure Papyrus
Use papyrus-template as the recommended starting point, then configure the site with TOML, Markdown, and asset overrides.
Start with
papyrus-template.
The template keeps the site repo small: config, profile data, posts, and
assets. The package provides the routes, layouts, post UI, collections, RSS,
robots, search hooks, profile pages, and theme CSS.
Start from the template
Create a repository from papyrus-template, then install dependencies:
pnpm install
pnpm devshThe template depends on the package:
{
"dependencies": {
"astro-papyrus": "^0.2.2"
}
}jsonUse the npm package for normal sites. It is the stable path for template users because it resolves like any other dependency:
pnpm add astro-papyrus@^0.2.2shUse a pinned GitHub dependency only when testing unreleased Papyrus work or waiting for a new npm release to pass the registry maturity window:
pnpm add github:marcelofpfelix/papyrus#0.2.2shA branch name is convenient for preview work, but a tag or commit SHA is safer for real sites because it makes rebuilds repeatable.
It enables Papyrus in Astro:
import { definePapyrusAstroConfig } from "astro-papyrus/astro";
export default definePapyrusAstroConfig();jsOptional Astro plugins
Papyrus exports small Astro integrations for features that should not be active on every site. Add only the ones the site needs:
import { definePapyrusAstroConfig } from "astro-papyrus/astro";
import {
papyrusBasePath,
papyrusLinkValidator,
papyrusMdTxt,
papyrusSiteGraph,
} from "astro-papyrus/plugins";
export default definePapyrusAstroConfig({
plugins: [
papyrusBasePath(),
papyrusMdTxt(),
papyrusSiteGraph(),
papyrusLinkValidator(),
],
});jspapyrusBasePath()rewrites root-relative links and images in Markdown when Astro is deployed below a base path. Components continue to use Papyrus’swithBase()helper.papyrusMdTxt()publishes each public post at/posts/<slug>.md.txtwith minimal title and description frontmatter. Its AST cleaner followsstarlight-md-txtand removes MDX-only wrappers while preserving their readable content.papyrusSiteGraph()adds/graph/from the existingpublic/ai/graph.jsonindex. The normal Papyrus build generates that file before Astro runs. Papyrus keeps its small SVG renderer because the currentstarlight-site-graphrelease does not run correctly with Astro 7.papyrusLinkValidator()checks Markdown links with source positions and rendered internal links after the Astro build. It fails on missing routes, including sites deployed below a base path.
These integrations adapt useful ideas from the Starlight plugin ecosystem to Papyrus’s routes and data. They are not a compatibility layer for running arbitrary Starlight plugins unchanged.
Papyrus uses Pagefind as its single search engine. It intentionally does not
wrap starlight-telescope, because that would add Starlight and Fuse to a site
that already has a generated Pagefind index.
Exact upstream releases, commits, adaptation boundaries, and licenses are
listed in THIRD_PARTY_NOTICES.md in the package.
Custom routes can read the same TOML file through loadPapyrusConfig:
import { loadPapyrusConfig } from "astro-papyrus/config";tsIt also reuses the Papyrus content collection:
export { collections } from "astro-papyrus/content";tsPapyrus adds these routes:
| Route | Source |
|---|---|
/ | Home page with latest posts and project cards |
/posts/ | Public post list |
/posts/[...slug]/ | Post detail page |
/projects/ | Project cards from src/data/projects.toml |
/profile/, /profile/print/, /profile/ast/ | Profile and CV pages from src/data/profile.toml |
/tag/ and /tag/[tag]/ | Tag index and tag detail pages |
/404.html | Helpful not-found page |
/rss.xml | Main RSS feed |
/robots.txt | Robots file with sitemap URL |
Because the pages are injected by the package, the template does not need a
src/pages tree unless your site adds custom routes.
Know src vs public
Papyrus follows Astro’s normal file boundary: src/ is source, and public/
is copied to the deployed site as-is.
Use src/ for files Astro should read, transform, type-check, or route during
the build:
src/content/posts/*.mdfor postssrc/content/posts/**/folder.tomlfor ordered collectionssrc/content.config.tsfor the Papyrus content collection exportsrc/data/profile.tomlfor the profile and CV sourcesrc/pages/*.astroonly when you need a custom route
Use public/ for files that should keep the same URL and contents after build:
public/logo.svg,public/favicon.svg, andpublic/site.webmanifestpublic/images/*for covers, avatars, and project images- generated artifacts such as
public/cv/resume.json,public/cv/profile.md,public/ai/*,public/rss/tags/*, andpublic/pagefind/*
Do not hand-edit generated files in public/. Edit the source in src/,
papyrus.config.toml, or src/data/profile.toml, then regenerate artifacts.
Edit the right file
For normal site work, start with these files:
| Goal | Edit |
|---|---|
| Site title, description, navigation, theme, feature flags, homepage counts, and post-card defaults | papyrus.config.toml |
| Project cards | src/data/projects.toml |
| Add or edit posts | src/content/posts/*.md |
| Add ordered docs or guide sections | src/content/posts/<folder>/<folder>.toml plus Markdown posts |
| Change the profile, CV, links, skills, dates, and print color | src/data/profile.toml |
| Change logos, favicons, covers, avatars, and project images | public/ assets |
The package repo has many files because it owns the reusable components, routes, scripts, styles, and demo fixtures. A site repo should stay closer to the template shape: config, content, profile data, and assets.
Add posts
Posts live in src/content/posts. A minimal post needs a title, description,
date, and optional tags.
---
title: Publishing with Papyrus
description: A short implementation note published from a Papyrus-powered site.
date: 2026-07-10T09:00:00.000Z
tags: [astro, papyrus]
cover: /images/cover.svg
---
Write the post body in Markdown.mdPapyrus handles list pages, detail pages, adjacent links, tags, scheduled posts,
reading time, cover images, RSS entries, generated route paths, and generated
social preview cards. A post does not need cover frontmatter to get an Open
Graph/X sharing image. When a post has a cover, Papyrus uses it inside the
generated social card instead of pointing og:image directly at the original
cover file.
Use ogSourceImage when the best social-card visual is an image from the post
body instead of the article cover:
---
title: Publishing with Papyrus
description: A short implementation note published from a Papyrus-powered site.
date: 2026-07-10T09:00:00.000Z
cover: /images/article-cover.jpg
ogSourceImage: /images/body-diagram.jpg
---mdThe preview image order is:
ogImagepoints to a finished custom social card.ogSourceImagefeeds a body image into the generated social card.coverfeeds the visible post cover into the generated social card.- no image creates a generated text-only social card.
Use ogImage only when you already have a finished 1200x630 social image and
want to bypass the generated card for that post.
Edit the profile
The profile page reads src/data/profile.toml.
[user]
name = "Site Author"
title = "Software Engineer"
bio = "Writer and software engineer"
location = "Lisbon, Portugal"
print_color = "#37474F"
email_user = "hello"
email_domain = "site.test"
sections = ["about", "experience", "education", "skills"]tomlThe same profile data can be exported to JSON and Markdown with:
pnpm run cv:exportshNext steps
- Configure the site in Site config.
- Learn content features in Markdown authoring guide.
- Use ordered docs or guides with Collections.
- Review the package boundary in Papyrus package shape.
/posts/install-configure-papyrus/
Part of Papyrus docs.