Skip to content
✨ Publier v1 is live — a polished docs platform built for the open web.
On this page

Troubleshooting

Solutions to common issues setting up, running, and building a Publier site.

publier.config.yaml isn’t being picked up

Malformed YAML or invalid supported configuration stops setup; Publier does not warn and continue with defaults. Read the parse error or Invalid publier.config.yaml diagnostic in the dev-server or build output. The file must include a site mapping with a non-empty site.name.

Validate the YAML syntax with any linter (e.g. yamllint) or against the published JSON Schema. publier doctor checks whether the YAML parses; it does not validate the full schema. Use the published JSON Schema for option validation.

Dev server refuses to start

Publier’s dev server must run under Bun — publier dev spawns bunx --bun astro dev internally. Equivalent direct invocation:

Terminal window
bunx --bun astro dev

Scaffolded projects ship dev/build/preview scripts that already point at bunx --bun astro, so bun run dev works out of the box. Only hand-rolled scripts that call astro through Node (e.g. plain astro dev under npm run) need adjusting.

Q30 — module already imported (or “duplicate runtime”)

Qwik v2 throws Q30 when two instances of @qwik.dev/core end up in the module graph — typically because Vite pre-bundled a dependency that also imports Qwik. Publier guards against this automatically. If you see Q30 after customizing astro.config.ts, check that you are not spreading the existing vite plugin array:

astro.config.ts — WRONG
vite: {
plugins: [...(config.vite?.plugins ?? []), myPlugin()],
}

Astro already concatenates — spreading doubles every plugin. Pass only new entries:

astro.config.ts — CORRECT
vite: {
plugins: [myPlugin()],
}

Q14 — Invalid JSX node during astro build

Q14 during static generation almost always traces back to one of two patterns:

  1. Importing a Qwik island from MDX — @publier/shell/qwik exports AskAi, a component$() island. Importing it directly at the top of an MDX file can cause the SSG pipeline to emit a fragment containing stale vnodes. Move the import into a small .tsx wrapper component and import that wrapper instead. (Components from @publier/shell/components are plain Astro — no Q14 risk there.)
  2. Components that render <slot /> conditionally — an {cond && <slot />} pattern inside a Qwik component$ trips Q14 on SSG. Always render the slot unconditionally and let the conditional live inside the slot body.

My sidebar doesn’t show a new page

Check in order:

  1. Is the file under src/content/docs/? Only files under the docs collection appear in the docs sidebar.
  2. Does it have the required title: in the frontmatter? A missing title fails content validation; check the build or dev-server error.
  3. Did you set sidebar.hidden: true in the frontmatter? That filters the page even though it still builds as a route.
  4. Did you restart the dev server after adding a new directory? Astro’s content collection watcher occasionally misses a brand-new folder; restart publier dev to pick it up.

Search dialog shows nothing

The Pagefind index is produced at build time — the dev server serves whatever index was written by the last build. Two fixes:

  • Test search after a build: publier build && bun run preview — Cmd/Ctrl+K works on the preview server identically to production.
  • Inspect the index directly: after publier build, dist/pagefind/ holds the WASM index and fragment files. An empty directory means the production build did not complete — confirm your PUBLIER_TOKEN is valid and re-run the build.

If you set docsShell({ search: false }) in astro.config.ts, shell skips wiring the Pagefind dialog entirely — Cmd/Ctrl+K does nothing and the nav SearchButton becomes a no-op.

My component renders but doesn’t respond to clicks

Most interactive components ship as plain Astro + web components — no client directive needed. Tabs, Accordion, Tooltip, CopyButton, ImageZoom, ColorSwatch, PackageInstall, and all OpenAPI primitives activate automatically once their markup is on the page.

Only one user-facing component is a Qwik island and needs client:load:

<AskAi client:load />

docsShell() mounts the site-wide search dialog without a per-page import or client directive. Keep the scaffold’s explicit pagefind() integration to generate its production index; see Search.

If you add a client directive to an Astro component (<Tabs client:idle />), Astro will warn at build time that the directive is ignored — remove it. If an Astro component doesn’t activate, the root cause is almost always one of: the page isn’t rebuilding (restart publier dev), the page failed to load required runtime scripts (check the browser console for errors), or CSS scoping hid the interactive area (inspect element to see if the hit target is visible and pointer-events aren’t none).

content.config.ts at the project root is ignored

Keep the scaffold’s content configuration at src/content.config.ts. A config at the project root is ignored — your collections won’t be registered, and every page in src/content/docs/ will 404.

my-site/
├── src/
│ ├── content.config.ts ← CORRECT
│ └── content/
└── content.config.ts ← IGNORED (legacy location)

@qwik.dev/astro peer-dep warning

docsShell() warns when the Qwik integration is not registered. Install its packages if needed:

Terminal window
pnpm add @qwik.dev/astro @qwik.dev/core

Import qwik from @qwik.dev/astro and add qwik({ clientRouter: true }) to integrations yourself, then restart the dev server. Installing the package alone does not register it. Keep the integration order shown in Configuration; scaffolded projects already include this entry.

OG image doesn’t render

@publier/native depends on two optional peers that are not installed by default:

Terminal window
pnpm add satori @resvg/resvg-js

The error message includes the exact command when these are missing.

check-types recurses into package internals

Run bun run check-types and see errors inside node_modules/@publier/...? Some Publier packages ship TypeScript source (rather than pre-compiled .d.ts), so tsc walks into them by default. Two workarounds:

  • Add "skipLibCheck": true to your project’s tsconfig.json — cheapest fix, skips type-checking of all node_modules.
  • Use a narrower tsconfig.check.json that excludes node_modules/@publier/ from the checked paths while keeping type checks for the rest of your dependencies.