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 Bun — publier dev spawns bunx --bun astro dev internally. Equivalent direct invocation:
bunx --bun astro devScaffolded 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:
vite: { plugins: [...(config.vite?.plugins ?? []), myPlugin()],}Astro already concatenates — spreading doubles every plugin. Pass only new entries:
vite: { plugins: [myPlugin()],}Q14 — Invalid JSX node during astro build
Q14 during static generation almost always traces back to one of two patterns:
- Importing a Qwik island from MDX —
@publier/shell/qwikexportsAskAi, acomponent$()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.tsxwrapper component and import that wrapper instead. (Components from@publier/shell/componentsare plain Astro — no Q14 risk there.) - Components that render
<slot />conditionally — an{cond && <slot />}pattern inside a Qwikcomponent$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:
- Is the file under
src/content/docs/? Only files under thedocscollection appear in the docs sidebar. - Does it have
title:in the frontmatter? Without it, the page is filtered out ofbuildSidebar. - Did you set
sidebar.hidden: truein the frontmatter? That filters the page even though it still builds as a route. - Did you restart the dev server after adding a new directory? Astro’s content collection watcher occasionally misses a brand-new folder; restart
publier devto 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 yourPUBLIER_TOKENis 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:
pnpm add @qwik.dev/astro @qwik.dev/coreThen 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:
pnpm add satori @resvg/resvg-jsThe 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": trueto your project’stsconfig.json— cheapest fix, skips type-checking of allnode_modules. - Use a narrower
tsconfig.check.jsonthat excludesnode_modules/@publier/from the checked paths while keeping type checks for the rest of your dependencies.