vuejs/vue · error · Error
render function or template not defined in component: ${vm.$
Error message
render function or template not defined in component: ${vm.$options.name || vm.$options._componentTag || 'anonymous'} What it means
Thrown by normalizeRender during SSR when a component instance has neither a render function nor a template in its $options. The SSR renderer must produce VNodes; without a render or template it cannot. The component name is included (or 'anonymous' if unset, or _componentTag if a tag was used in the parent template).
Source
Thrown at packages/server-renderer/src/render.ts:49
}
const normalizeRender = vm => {
const { render, template, _scopeId } = vm.$options
if (isUndef(render)) {
if (template) {
const compiled = ssrCompileToFunctions(
template,
{
scopeId: _scopeId,
warn: onCompilationError
},
vm
)
vm.$options.render = compiled.render
vm.$options.staticRenderFns = compiled.staticRenderFns
} else {
throw new Error(
`render function or template not defined in component: ${
vm.$options.name || vm.$options._componentTag || 'anonymous'
}`
)
}
}
}
function waitForServerPrefetch(vm, resolve, reject) {
let handlers = vm.$options.serverPrefetch
if (isDef(handlers)) {
if (!Array.isArray(handlers)) handlers = [handlers]
try {
const promises: Promise<any>[] = []
for (let i = 0, j = handlers.length; i < j; i++) {
const result = handlers[i].call(vm, vm)
if (result && typeof result.then === 'function') {
promises.push(result)View on GitHub (pinned to 9e88707940)
Solutions
- Add a render function or template to the component's options.
- If the component is meant to be renderless, give it a no-op render: { render: h => h() }.
- Ensure vue-loader's SSR build emits the render function; check that the .vue file has a <template> or a render in <script>.
- Verify the component is the one named in the error (trace the parent that mounts it).
Example fix
// before
export default { name: 'MyComponent' }
// after
export default {
name: 'MyComponent',
render(h) {
return h('div', this.$slots.default)
}
} Defensive patterns
Strategy: validation
Validate before calling
function assertComponentRenderable(vm: any): void {
const { render, template } = vm.$options
if (render === undefined && template === undefined) {
throw new Error(
`Component ${vm.$options.name || 'anonymous'} has no render function and no template; ` +
`cannot SSR. Add a <template> or render(h) to the component.`
)
}
}
// before SSR
assertComponentRenderable(app) Type guard
function isRenderableComponent(opts: any): boolean {
return typeof opts.render === 'function' || typeof opts.template === 'string'
} Try / catch
renderer.renderToString(app, (err, html) => {
if (err && err.message.includes('render function or template not defined in component')) {
// the component name is in the message; find it and add a render
console.error(err.message)
}
}) Prevention
- Ensure every component registered for SSR has either a <template> block or a render function.
- For renderless/abstract components used only for logic, provide a no-op render: () => h().
- Audit the component tree at startup and reject any component missing both render and template.
- Run SSR smoke tests in CI to catch missing-render issues before deploy.
When it happens
Trigger: An SSR'd component has $options.render === undefined and $options.template === undefined. This happens with components that only define a render function conditionally, components that rely on a mixin/template loader that didn't run on the server, or empty placeholder components.
Common situations: A component imported on the client via a render function that is stripped by tree-shaking. A functional component missing its render. Using a component definition that is just { name: 'Foo' } with no template/render. A vue-loader misconfiguration drops the render/template at build time for SSR.
Related errors
- render cannot be called without a template.
- function template is only supported in renderToString.
- \n[31m${err}${trace}[39m\n
- createStream cannot be called without a template.
- Content placeholder not found in template.
AI-assisted analysis of vuejs/vue@9e88707940 (2026-08-11).
Data as JSON: /api/errors/8c601e5da25a9a4d.
Report an issue: GitHub.