Rocket
On this page

Troubleshooting#

Use this page to map a symptom to the part of Rocket most likely involved. When in doubt, first run the dev server from a clean terminal so you can see the full error output.

Dev server will not start#

Check the Node.js version:

node --version

Rocket requires Node.js 22 or newer.

Confirm rocket-config.js has a default export:

export default {
  includeGlobs: ['docs/**/*.rocket.{md,js}'],
};

If port 8888 is already in use, change it with adjustDevServerConfig:

export default {
  includeGlobs: ['docs/**/*.rocket.{md,js}'],
  adjustDevServerConfig: config => ({
    ...config,
    port: 3000,
  }),
};

Page is missing#

Likely causes:

Fixes:

npx rocket start

Then press Ctrl+R in the terminal to restart after adding new directories or changing config.

Page is not in the menu#

Check the Page config:

export const config = {
  path: '/api/components',
  menu: false,
};

menu: false hides a Page from the tree. menu.noLink keeps it visible but non-clickable. Parameterized Pages should usually use menu: false.

If the Page appears in the wrong group, check menu.parent.

Table of contents fails#

Markdown Pages may have only one h1. The table-of-contents tree also expects heading levels to move one level at a time.

This is valid:

# Page

## Section

### Detail

This can fail:

# Page

#### Detail

Use menu-exclude when a heading should not appear in the table of contents.

JavaScript Page build fails#

A JavaScript Page with a concrete config.path can build as static output. If the failing Page path contains route parameters, Rocket cannot render one static document for every possible value yet. Set render: 'server' and configure an adapter:

export const config = {
  path: '/api/:name',
  render: 'server',
  menu: false,
};

Without an adapter, rocket build fails when it finds server-rendered Pages. If the Page is meant to stay static, keep render unset or set it to 'static', and use a concrete path such as /api/time.

Server-rendered Page returns the wrong type#

A JavaScript Page may return a Response, string, plain object, null, or undefined.

If you need custom status or headers, return a Response directly:

export default async () => {
  return new Response('Not found', {
    status: 404,
    headers: {
      'Content-Type': 'text/plain; charset=utf-8',
    },
  });
};

Custom element is unregistered#

Rocket validates authored custom element tags in Markdown Pages. For a tag such as <acme-card></acme-card>, the Page must either register it:

const acmeCardFile = new URL('../components/AcmeCard.js', import.meta.url).href;

export const components = {
  'acme-card': {
    file: acmeCardFile,
    className: 'AcmeCard',
    loading: 'server',
  },
};

Or define it as a Page-local Custom Element:

```js client
class AcmeCard extends HTMLElement {}
customElements.define('acme-card', AcmeCard);
```

The tag name in customElements.define must be a literal string. Computed tag names are not accepted as Page-local ownership.

Registered Component does not render#

Check:

For browser-only components, use loading: 'client'.

Hydration does not run#

Check the Loading Strategy:

loading: 'hydrate:onVisible';
loading: 'hydrate:onClick';
loading: "hydrate:onMedia('(max-width: 768px)')";

For hydrate:onMedia, include the media query in quotes inside the strategy string.

Use the browser Network tab to confirm the component module was requested when the condition should resolve. Use the Console tab to check for errors while upgrading the custom element.

Assets 404#

Prefer resolve for browser-facing source assets:

import { resolve } from '@rocket/js/resolve.js';

const logo = resolve('../assets/logo.svg', import.meta);

For Registered Component modules, use new URL(..., import.meta.url).href instead:

const componentFile = new URL('../components/AcmeCard.js', import.meta.url).href;

If a package asset fails to resolve, check that the package exposes it through its exports map.

Standalone Demo URL fails#

Standalone Demo URLs use this shape:

<page path>/_demo/<demo export name>/

Check:

Debugging tips#

Add focused logging in the failing layer:

import { atlasDocLayout } from '@rocket/js/layouts/atlasDoc.js';
import { globalData } from '../globalData.js';

export const layout = pageData => {
  console.log('Page title:', pageData.title);
  return atlasDocLayout(pageData, globalData);
};

For JavaScript Pages, log the request and params:

export default async (request, context) => {
  console.log(new URL(request.url).pathname, context.params);
  return 'ok';
};

Remove temporary logging before committing.

Getting help#

When opening an issue or asking in Discord, include:

Support links: