Troubleshooting
Fix common setup, build, styling, content, and deployment problems in Ardo projects.
On this page
Most Ardo issues come from the boundary between Ardo's CLI configuration, the routes in app/routes, and Markdown/MDX content. Start with the section that matches the symptom, then compare the integration with a version-matched Basic example.
Installation Issues
Cannot find module 'ardo'
Make sure you have installed all required dependencies:
pnpm add ardo@6
Node.js Version Error
Ardo requires Node.js 22.22.0 or higher. Check your version:
node --version
If you need to upgrade, consider using nvm or fnm.
Build Issues
Failed to resolve import
Ardo's CLI adds its build integration automatically. Put site settings in optional ardo.config.ts:
import { defineArdoConfig } from "ardo/config"
export default defineArdoConfig({
title: "My Documentation",
})
Use vite.config.ts only when you need additional Vite plugins or Vite-specific settings; the Ardo
CLI supplies its own integration.
Documentation package boundary
Ardo treats the Vite project root as an independent documentation package. Keep its own
package.json and install its declared dependencies in that project's node_modules.
An installation in an ancestor or monorepo root does not satisfy a missing local installation.
Ardo owns the React, React DOM, Vite, and default icon installations. Imports of these managed packages resolve to Ardo's dependency tree. Other direct application imports must be declared in the docs package, even when another dependency already uses that package. Dependencies may use their own declared transitive dependencies. Normal pnpm links to packages in its virtual store are supported; the store location does not change package ownership.
Keep custom components inside the docs project, for example in app/components/. Relative imports,
Vite aliases, and symlinks to component source in sibling workspace packages fail in development
and builds. Workspace package links to component source also fail. Install a published package
when you need a packaged component library. Ardo's own workspace link is supported for framework
development, using its built dist files.
Ardo bundles the application's dependencies for SSR, including its React runtime.
Components and the server renderer use that same bundled runtime. There is no per-component
ssr.noExternal list to maintain. A missing dependency produces an [ardo] error rather than
falling back to a parent installation. During development, Vite automatically optimizes SSR
dependencies so CommonJS libraries can run in the same module graph.
This boundary applies to the application module graph. Explicit native API and content-source inputs can still be read to generate documentation; they do not make outside component source available to application imports.
TypeScript Errors in Routes
Ardo generates its route table as a virtual module; there are no generated router types to rebuild. Check the authored route and its imports:
- Check that
tsconfig.jsonextendsardo/tsconfigand includes yourappdirectory - Import React APIs and types from
ardo/react - Run
pnpm exec tsc --noEmitto see the source error, then restart your editor's TypeScript server if its diagnostics remain stale - For optional API or collection routes, fix errors in their source inputs and configuration rather than editing generated Markdown
Build Fails with Memory Error
For large documentation sites, increase Node.js memory:
NODE_OPTIONS=--max-old-space-size=4096 pnpm build
Development Issues
Hot Reload Not Working
- Check that you're editing files in the
app/routes/directory - Ensure Vite dev server is running
- Try restarting the dev server
Styles Not Applied
Ardo loads its own stylesheet for every site. If your own styles don't apply, check that app/root.tsx imports your CSS file, and see Stylesheet ownership and cascade for how Ardo's ardo cascade layer interacts with yours.
Search Not Working
Search data is generated from the route tree in development and during the production build. A separate build is not needed before using development search.
- Confirm the document is under
app/routes/or an enabled content source - Try a word from a heading or paragraph in a Markdown or MDX page
- Check the browser console and development terminal for a failed search-index module request
- Restart the dev server if a configuration change added a new content source
Content Issues
Markdown Not Rendering
Check that your file:
- Has a
.mdor.mdxextension - Is located in the
app/routes/directory - Has valid frontmatter (if using frontmatter)
Code Blocks Not Highlighted
Syntax highlighting uses Ferriki. Ensure you specify the language:
```javascript
const foo = "bar"
```
See Ferriki's standard assets for supported languages and themes. An unknown language produces a warning and renders as plain text.
Native Engine or Asset Loading Fails
Ardo requires Node.js 22.22 or newer and native binaries for Linux or Windows on x64/arm64, or macOS on Apple Silicon. Keep optional dependencies enabled when installing packages.
Ferriki downloads standard language and theme assets on first use. For offline CI, populate and persist a cache beforehand, then set FERRIKI_CACHE_DIR to its location and FERRIKI_ASSETS_REMOTE=0 to disable downloads. A missing theme or native binary fails the build; see Ferriki troubleshooting.
CodeBlock Not Highlighted in .tsx Routes
The ardo:codeblock-highlight plugin requires a static language prop. If the language is dynamic (from a variable or expression), build-time highlighting is skipped and the code renders as plain text.
Code can be provided as plain text children, template literal children, or via the code prop:
import { ArdoCodeBlock } from "ardo/ui"
;<ArdoCodeBlock language="typescript">const x = 42</ArdoCodeBlock>
For fully dynamic code, use the highlightCode utility from ardo/vite at build time:
import { highlightCode } from "ardo/vite"
const html = await highlightCode(dynamicCode, "typescript")
Images Not Loading
Use relative paths from your markdown file:

Or absolute paths from the public directory:

Deployment Issues
404 on Page Refresh
Ardo writes one HTML file per page and uses ordinary document navigation. Deploy the complete build/client/ directory and configure the host to serve directory indexes, such as /guide/intro/index.html for /guide/intro/. Preserve the configured base path and serve Ardo's 404.html for missing pages. See Deployment for host-specific settings.
If the root URL itself returns 404 during local development, add app/routes/home.tsx or app/routes/index.mdx. Check that the home page links to an existing document before building again.
Base Path Issues
If deploying to a subdirectory, set the base option in ardo.config.ts:
import { defineArdoConfig } from "ardo/config"
export default defineArdoConfig({
base: "/my-docs/",
})
Getting Help
If your issue isn't listed here:
- Check the GitHub Issues for similar problems
- Open a GitHub Discussion for questions
- Create a new issue with a minimal reproduction