Skip to content
CtrlK

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:

  1. Check that tsconfig.json extends ardo/tsconfig and includes your app directory
  2. Import React APIs and types from ardo/react
  3. Run pnpm exec tsc --noEmit to see the source error, then restart your editor's TypeScript server if its diagnostics remain stale
  4. 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

  1. Check that you're editing files in the app/routes/ directory
  2. Ensure Vite dev server is running
  3. 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.

  1. Confirm the document is under app/routes/ or an enabled content source
  2. Try a word from a heading or paragraph in a Markdown or MDX page
  3. Check the browser console and development terminal for a failed search-index module request
  4. Restart the dev server if a configuration change added a new content source

Content Issues

Markdown Not Rendering

Check that your file:

  1. Has a .md or .mdx extension
  2. Is located in the app/routes/ directory
  3. 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:

![Alt text](./images/screenshot.png)

Or absolute paths from the public directory:

![Alt text](/images/screenshot.png)

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:

  1. Check the GitHub Issues for similar problems
  2. Open a GitHub Discussion for questions
  3. Create a new issue with a minimal reproduction
Edit this page on GitHubLast updated: October 23, 2026