{"record":{"id":"31f05970952dc357","repo":"withastro/astro","slug":"the-renderer-you-passed-isn-t-valid-a-renderer-is","errorCode":null,"errorMessage":"The renderer you passed isn't valid. A renderer is usually an object that exposes the `check` and `renderToStaticMarkup` functions.\nUsually, the renderer is exported by a /server.js entrypoint e.g. `import renderer from '@astrojs/react/server.js'`","messagePattern":"The renderer you passed isn't valid\\. A renderer is usually an object that exposes the `check` and `renderToStaticMarkup` functions\\.\nUsually, the renderer is exported by a /server\\.js entrypoint e\\.g\\. `import renderer from '@astrojs/react/server\\.js'`","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/container/index.ts","lineNumber":375,"sourceCode":"\t * import reactRenderer from \"@astrojs/react/server.js\";\n\t * import vueRenderer from \"@astrojs/vue/server.js\";\n\t * import customRenderer from \"../renderer/customRenderer.js\";\n\t * import { experimental_AstroContainer as AstroContainer } from \"astro/container\"\n\t *\n\t * const container = await AstroContainer.create();\n\t * container.addServerRenderer(reactRenderer);\n\t * container.addServerRenderer(vueRenderer);\n\t * container.addServerRenderer(\"customRenderer\", customRenderer);\n\t * ```\n\t *\n\t * @param options {object}\n\t * @param options.name The name of the renderer. The name **isn't** arbitrary, and it should match the name of the package.\n\t * @param options.renderer The server renderer exported by integration.\n\t */\n\tpublic addServerRenderer(options: AddServerRenderer): void {\n\t\tconst { renderer } = options;\n\t\tif (!renderer.check || !renderer.renderToStaticMarkup) {\n\t\t\tthrow new Error(\n\t\t\t\t\"The renderer you passed isn't valid. A renderer is usually an object that exposes the `check` and `renderToStaticMarkup` functions.\\n\" +\n\t\t\t\t\t\"Usually, the renderer is exported by a /server.js entrypoint e.g. `import renderer from '@astrojs/react/server.js'`\",\n\t\t\t);\n\t\t}\n\t\tif (isNamedRenderer(renderer)) {\n\t\t\tthis.#pipeline.manifest.renderers.push({\n\t\t\t\tname: renderer.name,\n\t\t\t\tssr: renderer,\n\t\t\t});\n\t\t} else if ('name' in options) {\n\t\t\tthis.#pipeline.manifest.renderers.push({\n\t\t\t\tname: options.name,\n\t\t\t\tssr: renderer,\n\t\t\t});\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t'The renderer name must be provided when adding a server renderer that is not a named renderer.',\n\t\t\t);","sourceCodeStart":357,"sourceCodeEnd":393,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/container/index.ts#L357-L393","documentation":"`experimental_AstroContainer.addServerRenderer` validates that the passed renderer object exposes both a `check` and a `renderToStaticMarkup` function — the two methods Astro's SSR pipeline calls to detect and render a framework component. Missing either makes the renderer unusable, so the container rejects it immediately.","triggerScenarios":"Calling `container.addServerRenderer({ renderer: someObj })` where `someObj` lacks `check` or `renderToStaticMarkup`; importing the wrong entrypoint (e.g. the client `client.js` instead of `server.js`); passing a default-export wrapper object instead of the renderer itself.","commonSituations":"Importing from the package root rather than the `/server.js` subpath; passing a hand-written partial renderer for testing; version mismatch where a renderer integration changed its export shape; tree-shaking/TypeScript `import type` stripping a side-effect-only export.","solutions":["Import the renderer from its documented server entrypoint, e.g. `import reactRenderer from '@astrojs/react/server.js'`.","Confirm the object has both `check` and `renderToStaticMarkup` functions before passing it.","If writing a custom renderer, implement both methods on the exported object.","Check the renderer package's `package.json#exports` for the correct `server` subpath for your version."],"exampleFix":"// before\nimport react from '@astrojs/react';\ncontainer.addServerRenderer({ renderer: react });\n// after\nimport reactRenderer from '@astrojs/react/server.js';\ncontainer.addServerRenderer(reactRenderer);","handlingStrategy":"type-guard","validationCode":"function isValidRenderer(r) {\n  return r && typeof r.check === 'function' && typeof r.renderToStaticMarkup === 'function';\n}\nif (!isValidRenderer(renderer)) throw new Error('renderer missing check/renderToStaticMarkup');","typeGuard":"function isValidServerRenderer(r): r is { check: Function; renderToStaticMarkup: Function } {\n  return !!r && typeof r.check === 'function' && typeof r.renderToStaticMarkup === 'function';\n}","tryCatchPattern":null,"preventionTips":["Always import renderers from the documented `/server.js` subpath.","Validate a renderer object before passing it to `addServerRenderer`.","Implement both `check` and `renderToStaticMarkup` on custom renderers."],"tags":["container","ssr","renderer","api-misuse"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}