v3.1.0

Changelog version 3.1.0

Changelog v3.1.0Link

FeatureLink

  • Feature:
  • PluginContext.outDir — new readonly property exposing the build output directory (e.g., 'dist/') to plugin lifecycle hooks, eliminating the need for plugins to hardcode output paths
  • --turbo mode for boltdocs build — Sätteri-powered build pipeline with native WASM parsing, critical CSS extraction, and Shiki syntax highlighting
  • Available via CLI: boltdocs build --turbo
  • Native WASM MDX parser (satteri) replaces @mdx-js/rollup for faster compilation
  • Critical CSS extraction via zig-critters (WASM) removes unused CSS
  • Shiki syntax highlighting with dual light/dark themes
  • Remark/rehype plugin adapter layer supports standard unified plugins (e.g. mermaid)
  • Fallback to standard MDX compiler if satteri fails
  • Collections hooks API — simplified hooks for collection data access
  • usePosts(collection?) — defaults to "blog", returns all filtered posts
  • usePost() — reads current post from context inside post.tsx
  • useRecentPosts(collection?, count?) — defaults to "blog" with count of 5
  • Removed useCollectionList (was redundant)
  • Feature Flags & Drafts — control page visibility per environment
  • drafts config: { visible?: boolean, environments?: string[] } — control draft visibility
  • featureFlags config: Record<string, boolean | string> — define flags, pages declare required flags
  • Draft badge in navbar when viewing draft pages
  • BOLTDOCS_DRAFTS=true env var to force draft visibility
  • PostHog integration — built-in analytics support for PostHog
  • Config: integrations.analytics.posthog.apiKey (required), host (optional, defaults to US cloud)
  • Session recording and autocapture off by default (opt-in via config)
  • EU cloud support: host: 'https://eu.i.posthog.com'
  • Injects PostHog JS snippet into <head> at build time (production only)
  • Client-side detection via window.posthog in useAnalytics() hook
  • Locale switching bug: Switching languages on collection pages (e.g., /blog) now correctly navigates to the localized version (e.g., /es/blog) instead of redirecting to /docs
  • Vercel analytics script fix: vercel.analytics and vercel.speedInsights now default to true if not specified in config, preventing accidental omission of analytics scripts
  • Native parser binary path lookup now includes bdocs-parser as a local fallback
  • Removed build:wrapper script from zig-critters package.json (was broken)
  • Fixed main field in zig-critters/package.json to point to wasm/index.mjs
  • Critical regex fix: __staticRouterHydrationData script removal regex was crossing </script> boundaries, eating the entire HTML structure (missing <body>, </head>, id="root"). Added negative lookahead (?!<\/script>) to prevent matching across script tags.
  • Locale bug fix: DefaultCollectionList now uses usePosts() which filters by current locale/version instead of useLoaderData() which bypassed filtering
  • Turbo mode fixes: Shiki syntax highlighting now produces correct HTML with merged class attributes; CSS parser handles escape sequences and edge cases in selectors; WASM memory model uses arena allocation for reliability
  • --turbo performance fixes: Fixed 5 issues causing turbo+cache to be slower than default mode:
  • Server build now correctly skips when client code is unchanged (was always running)
  • computeClientCodeHash no longer scans monorepo directories (packages/, scripts/, etc.)
  • Beasties critical CSS engine now skipped in turbo mode (uses zig-critters only)
  • Config resolution no longer runs twice in build pipeline
  • Turbo flag now propagated through entire pipeline to generateRoutes
  • useLocalizedTo home link fix: site:/ now resolves to /${activeLocale} instead of bare / when i18n is enabled, ensuring the navbar home button stays in the current locale
  • useI18n collection locale switching fix: Switching locale from a blog post page (/blog/en/post) now correctly produces /blog/es/post instead of /en/blog/es/post
  • useI18n collection list locale switching fix: Switching locale from a collection root page (e.g., /blog) no longer navigates away — collection root URLs are locale-independent
  • SSG SEO meta tags fix: Blog post pages and other content pages now correctly render per-page <title>, og:title, og:description, and og:image meta tags in the static HTML. Previously, react-helmet-async's HelmetProvider was not populating the helmet context because isDocument evaluated to true in the SSG context (jsdom active). Fixed by forcing HelmetProvider.canUseDOM = false and using synchronous renderToString to guarantee Helmet lifecycle methods complete before HTML is serialized.
  • Duplicate meta tags cleanup: Removed redundant generic og:title, og:description, og:image, twitter:*, og:type, og:url, canonical, and <title> from injectHtmlMeta(). These were duplicates of what Helmet renders per-page via data-rh attributes. Each page now has a single set of SEO meta tags managed by react-helmet-async.
  • Beasties disabled: Critical CSS inlining via Beasties is now disabled by default. HTML pages no longer contain ~37 KB of inlined <style> tags. CSS loads once via external <link> and is cached by the browser. Reduces total HTML output by ~7.3 MB across all pages.
  • Duplicate crossorigin attribute fixed: The regex that adds crossorigin to <link rel="stylesheet"> now uses a negative lookahead to avoid duplicating the attribute when it's already present.
  • Duplicate EN locale removed: generateI18nFallbacks() now skips the default locale when generating fallback routes. Previously, English content was duplicated at both root level (/docs/api/cli) and locale-prefixed (/docs/en/api/cli), resulting in ~8 MB of identical HTML files.
  • Inline code styling fix: Added missing styles for inline <code> elements (backtick text). Previously, inline code rendered as plain unstyled text with no visual distinction. Now applies background, terracotta text color, padding, border-radius, and monospace font using the existing --color-code-bg and --color-code-text theme variables.
  • useLocalizedTo default locale prefix fix: Links like /docs/guides no longer incorrectly get prefixed with the default locale (e.g., /docs/en/guides). The hook now skips adding the locale prefix when activeLocale === defaultLocale, matching the behavior of the route generation system. Also fixes site:/ root links for the default locale.
  • Browser tab title fix: The <title> tag now renders correctly in the browser tab. Previously, helmet-compat.tsx unconditionally set HelmetProvider.canUseDOM = false, preventing Helmet from updating document.title. Now the flag is only set during SSG rendering (via __BOLTDOCS_SSG_RENDERING__ global), allowing Helmet to manage the title on client-side navigation.

Bug FixLink

  • Updated dependencies [, ]:
  • @bdocs/parser@1.1.0
  • @bdocs/ssg@0.2.0
Last updated on October 18, 2026

Was this page helpful?