Deploying ¶
CarvePress writes static files to outDir. This repo builds to .site and publishes that directory to GitHub Pages.
GitHub Pages ¶
The workflow in this repository runs on pushes to main, never deploys pull requests, and still builds pull requests so broken docs fail checks.
name: Pages
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: falseThe job uses Node 22, runs npm ci, npm run build, npm test, and npm run docs:build, then uploads .site with actions/upload-pages-artifact and deploys with actions/deploy-pages.
Base Path ¶
Project pages need base: '/carve-press/' because the site is served below https://markup-carve.github.io/carve-press/. Keep authored internal links rooted at the site route, such as /guide/getting-started; CarvePress rewrites rendered URLs with the configured base.
Route Manifest ¶
CarvePress writes a route manifest at routes.json by default. The file is a sorted JSON array of content routes and should be committed. On later builds, any route in the manifest that is no longer present must be covered by a redirect source from redirects or page redirectFrom, or the build fails.
Fix a missing route by restoring the page, adding redirectFrom to the page that replaced it, or adding a redirects entry in config. Redirect stubs are not written into the manifest, so removing a redirect later does not look like a removed content page. Set routeManifest: false to disable this check.
Netlify And Cloudflare Pages ¶
Set the build command to:
npm ci
npm run docs:buildPublish .site. CarvePress can also write a Netlify-style redirects file from the redirects config and page redirectFrom frontmatter; this dogfood site maps /old-guide/ to /guide/getting-started.
On GitHub Pages, redirect stubs are static HTML files. They return 200 and use a meta refresh, not an HTTP 301, because Pages serves static files.
If you use clean URLs with a host that needs explicit fallback routing, add redirects in publicDir:
/* /404.html 404
Any Static Host ¶
Upload the contents of .site to the configured base path. If you disable cleanUrls, links include concrete .html files.
Redirecting A Whole Section ¶
A prefix pattern moves a renamed section in one entry:
redirects: { '/docs/*': '/guide/*' }The pattern is expanded against the pages that actually exist, so each one gets its own stub - a static host cannot match a pattern at request time. The _redirects file keeps the single splat line for hosts that do understand one. A pattern whose target matches no page fails the build rather than emitting nothing.
robots.txt ¶
Every build writes robots.txt, advertising the sitemap when the site knows its own hostname:
User-agent: *
Allow: /
Sitemap: https://example.com/docs/sitemap.xml
Without a hostname the Sitemap: line is omitted rather than written relative, which is a line crawlers ignore. robots: false writes nothing, and a robots.txt of your own in publicDir is never replaced - a file you shipped is your answer to this question, and silently overriding it is the kind of thing discovered weeks later by a crawler doing the wrong thing.
Last updated