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

  1. Add a render function or template to the component's options.
  2. If the component is meant to be renderless, give it a no-op render: { render: h => h() }.
  3. Ensure vue-loader's SSR build emits the render function; check that the .vue file has a <template> or a render in <script>.
  4. 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

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


AI-assisted analysis of vuejs/vue@9e88707940 (2026-08-11). Data as JSON: /api/errors/8c601e5da25a9a4d. Report an issue: GitHub.