Deploy under a subpath
Serve a Baseline site from a subpath like /docs/ without breaking links, asset paths, canonical URLs, or the sitemap on the way.
Prerequisites
- Baseline registered in
eleventy.config.js. package.jsonwith"type": "module"and scripts (start,build).settings.urlset to the production origin (no trailing slash, no subpath).- You deploy to a subpath (e.g. a GitHub Pages project site, a reverse proxy, or a Netlify subdirectory).
Set pathPrefix in Eleventy's config export
Keep settings.url pointed at the origin and put the subpath on pathPrefix:
import baseline, { config as baselineConfig } from '@apleasantview/eleventy-plugin-baseline';
import settings from './src/_data/settings.js';
/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */
export default async function (eleventyConfig) {
await eleventyConfig.addPlugin(baseline(settings));
}
export const config = {
...baselineConfig,
pathPrefix: '/docs/' // include leading and trailing slash
};
Eleventy rewrites root-relative URLs with pathPrefix, and the sitemap picks it up through Eleventy's htmlBaseUrl filter.
Keep settings.url clean (origin only)
Deployment checks covers the env shape. Sitemap entries combine settings.url with pathPrefix automatically.
The head does not carry
pathPrefixtoday.The canonical,
og:url, the hreflang alternates and the JSON-LD@idvalues are built fromsettings.urlplus the page's own URL, and Eleventy'sHtmlBasePluginleaves an already-absolute URL alone. So on a site deployed under/docs/, in-page links and the sitemap readhttps://www.example.com/docs/about/while the canonical readshttps://www.example.com/about/.Putting the subpath in
settings.urlinstead is not the fix: it doubles the prefix on the links and the sitemap. Until this is closed, a subpath deployment ships head URLs that are one segment short.
Use root-relative asset and page links
Reference built assets and pages with leading slashes so Eleventy applies pathPrefix:
<link rel="stylesheet" href="/assets/css/index.css">
<script src="/assets/js/index.js" defer></script>
<a href="/getting-started/">Getting started</a>
Avoid hardcoded full URLs with the subpath baked in.
Build and inspect what comes out
- Dev:
npm start - Build:
npm run build - Open
dist/sitemap.xmland confirm URLs include/docs/. - Inspect a built page for asset and link URLs that include
/docs/. The canonical will not, per the warning above.
Preview under the same subpath you'll deploy to
- Serve
dist/from a subpath-capable server, or use Eleventy's preview with--pathprefix="/docs/"to spot broken links. - Click through pages and assets to confirm they resolve under
/docs/.
What goes wrong
Nearly everything that breaks a subpath deployment is a URL that pathPrefix could not reach. Eleventy rewrites root-relative URLs and leaves everything else alone, so a hardcoded https://www.example.com/docs/about/ and a slashless assets/js/index.js fail for the same reason from opposite directions: one is already absolute and the other is relative to wherever the page happens to be. Write every link and asset path with a leading slash and the rewrite has something to work with.
The other half is a mismatch between the prefix you build with and the prefix you deploy under. Building without pathPrefix and serving from /docs/ breaks every link, which is why the preview step above uses the same value you plan to ship. Going the other way, back to root hosting, means clearing pathPrefix again or every path gains a segment it no longer has.
And the one that looks like a fix and is not: putting the subpath in settings.url as well as pathPrefix, which doubles it into /docs/docs/ across links and the sitemap. The warning above has the detail.