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

Troubleshooting

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

publier.config.yaml isn’t being picked up

Publier logs a warning when it can’t parse the config. Check the dev-server output for a line like:

[publier] Failed to load ./publier.config.yaml: unexpected token at line 3 column 5. Using defaults.

Validate the YAML syntax with any linter (e.g. yamllint) or against the published JSON Schema. Running publier doctor also reports config validation errors against the current schema.

Dev server refuses to start

Publier’s dev server must run under Bunpublier 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 title: in the frontmatter? Without it, the page is filtered out of buildSidebar.
  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 />

Site-wide search is wired automatically — no import, no client directive.

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

Astro 6 requires the file at src/content.config.ts, not the project root. A config at the root is silently 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

Publier auto-detects @qwik.dev/astro. If the package is missing it logs:

[publier] @qwik.dev/astro not found — interactive islands unavailable.

Install it explicitly:

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

Then restart the dev server. Publier will wire it automatically — you do not need to add qwik({ clientRouter: true }) to integrations yourself (though doing so is also supported).

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.