import {themes as prismThemes} from 'prism-react-renderer'; import type {Config} from '@docusaurus/types'; import type * as Preset from '@docusaurus/preset-classic'; try { process.loadEnvFile(); } catch { // No `.env` file present; fall back to the ambient environment. } const analyticsScript = process.env.ANALYTICS_SCRIPT; const config: Config = { title: 'AliasVault', tagline: 'A privacy-first password manager with built-in email aliasing', favicon: 'assets/img/favicon.png', // Load the Inter webfont from the document with preconnect, instead of // a render-blocking `@import` in custom.css. `@import` of a remote stylesheet // serializes requests (CSS -> font CSS -> font files) and delays first paint; // discovering the in the initial HTML + warming the gstatic connection // improves LCP (a Core Web Vitals ranking signal). `display=swap` avoids FOIT. headTags: [ { tagName: 'link', attributes: {rel: 'preconnect', href: 'https://fonts.googleapis.com'}, }, { tagName: 'link', attributes: { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: 'anonymous', }, }, { tagName: 'link', attributes: { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap', }, }, ], url: 'https://docs.aliasvault.com', baseUrl: '/', // Emit every internal link and page output with a trailing slash so the // canonical URL is hit directly. Without this, links like /architecture or // /installation/script resolve to a directory and the server issues a 301 to // add the slash which can remove a custom non 80/443 port from the URL. trailingSlash: true, organizationName: 'aliasvault', projectName: 'aliasvault', onBrokenLinks: 'throw', // Treat .md as CommonMark (lenient) and .mdx as MDX. This keeps the large // body of migrated Markdown (shell snippets, angle brackets, braces) parsing // without JSX escaping issues, while still allowing MDX where we opt in. markdown: { format: 'detect', hooks: { onBrokenMarkdownLinks: 'warn', }, }, i18n: { defaultLocale: 'en', locales: ['en'], }, presets: [ [ 'classic', { docs: { routeBasePath: '/', sidebarPath: './sidebars.ts', editUrl: 'https://github.com/aliasvault/aliasvault/tree/main/docs/', showLastUpdateTime: true, }, blog: false, theme: { customCss: './src/css/custom.css', }, sitemap: { changefreq: 'weekly', priority: 0.5, // Emit (from git history, via showLastUpdateTime) so // crawlers can tell which pages changed and re-crawl them sooner. lastmod: 'datetime', }, } satisfies Preset.Options, ], ], plugins: [ [ // Redirects old jekyll pages to the new docusaurus pages, as well as handling redirects for future moved pages. '@docusaurus/plugin-client-redirects', { redirects: [ { to: '/installation/docker-compose/', from: [ '/installation/advanced/manual-setup', '/installation/advanced/manual-setup.html', ], }, { to: '/installation/script/', from: ['/installation/install', '/installation/install.html'], }, { to: '/installation/script/troubleshooting', from: [ '/installation/troubleshooting', '/installation/troubleshooting.html', ], }, { to: '/installation/script/update/', from: ['/installation/update', '/installation/update.html'], }, { to: '/installation/script/update/v0.22.0', from: [ '/installation/update/v0.22.0', '/installation/update/v0.22.0.html', ], }, { to: '/installation/script/update/v0.23.0', from: [ '/installation/update/v0.23.0', '/installation/update/v0.23.0.html', ], }, // private-vs-public-email moved from /misc into /installation, then // again under the /installation/docs/ category. { to: '/installation/docs/private-vs-public-email', from: [ '/installation/private-vs-public-email', '/installation/private-vs-public-email.html', '/misc/private-vs-public-email', '/misc/private-vs-public-email.html', ], }, // The /misc landing and dev/release docs were removed; point any // stale links at the closest surviving pages. { to: '/', from: ['/misc', '/misc.html'], }, { to: '/contributing/development/', from: [ '/misc/dev/release', '/misc/dev/release.html', '/misc/dev/release/git-versioning-strategy', '/misc/dev/release/git-versioning-strategy.html', '/misc/dev/release/manual-versioning', '/misc/dev/release/manual-versioning.html', '/misc/dev/release/release-checklist', '/misc/dev/release/release-checklist.html', ], }, // The Linux/macOS and Windows dev pages were merged into a single // "development-setup" page. { to: '/contributing/development/development-setup', from: [ '/contributing/development/linux-macos-development', '/misc/dev/linux-macos-development', '/misc/dev/linux-macos-development.html', '/contributing/development/windows-development', '/misc/dev/windows-development', '/misc/dev/windows-development.html', ], }, // Dev database operations is covered by the self-host install docs. { to: '/installation/script/advanced/database', from: [ '/contributing/development/database-operations', '/misc/dev/database-operations', '/misc/dev/database-operations.html', ], }, { to: '/contributing/development/', from: [ '/contributing/development/add-new-language', '/misc/dev/add-new-language', '/misc/dev/add-new-language.html', '/contributing/development/upgrade-ef-client-model', '/misc/dev/upgrade-ef-client-model', '/misc/dev/upgrade-ef-client-model.html', '/contributing/development/upgrade-ef-server-model', '/misc/dev/upgrade-ef-server-model', '/misc/dev/upgrade-ef-server-model.html', ], }, ], // Sections that moved keep their old URLs working. Each entry maps a // new path prefix back to where it used to live: // - /misc/dev/* tree → /contributing/development/* // - /browser-extensions/* → /installation/browser-extensions/* // - /mobile-apps/* → /installation/mobile-apps/* createRedirects(existingPath) { const moves: [string, string][] = [ ['/contributing/development', '/misc/dev'], ['/installation/browser-extensions', '/browser-extensions'], ['/installation/mobile-apps', '/mobile-apps'], ]; for (const [newPrefix, oldPrefix] of moves) { if (existingPath.startsWith(newPrefix)) { const oldPath = existingPath.replace(newPrefix, oldPrefix); // Directory/index routes end with "/"; don't append ".html" there. return oldPath.endsWith('/') ? [oldPath] : [oldPath, `${oldPath}.html`]; } } return undefined; }, }, ], // Inject the analytics