{"record":{"id":"9045ec7a1513c977","repo":"vuejs/core","slug":"vue-compiler-core-decodeentities-option-is-requ","errorCode":null,"errorMessage":"[@vue/compiler-core] decodeEntities option is required in browser builds.","messagePattern":"\\[@vue/compiler-core\\] decodeEntities option is required in browser builds\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/compiler-core/src/parser.ts","lineNumber":1050,"sourceCode":"\n  if (options) {\n    let key: keyof ParserOptions\n    for (key in options) {\n      if (options[key] != null) {\n        // @ts-expect-error\n        currentOptions[key] = options[key]\n      }\n    }\n  }\n\n  if (__DEV__) {\n    if (!__BROWSER__ && currentOptions.decodeEntities) {\n      console.warn(\n        `[@vue/compiler-core] decodeEntities option is passed but will be ` +\n          `ignored in non-browser builds.`,\n      )\n    } else if (__BROWSER__ && !__TEST__ && !currentOptions.decodeEntities) {\n      throw new Error(\n        `[@vue/compiler-core] decodeEntities option is required in browser builds.`,\n      )\n    }\n  }\n\n  tokenizer.mode =\n    currentOptions.parseMode === 'html'\n      ? ParseMode.HTML\n      : currentOptions.parseMode === 'sfc'\n        ? ParseMode.SFC\n        : ParseMode.BASE\n\n  tokenizer.inXML =\n    currentOptions.ns === Namespaces.SVG ||\n    currentOptions.ns === Namespaces.MATH_ML\n\n  const delimiters = options && options.delimiters\n  if (delimiters) {","sourceCodeStart":1032,"sourceCodeEnd":1068,"githubUrl":"https://github.com/vuejs/core/blob/a2b40db9a83b36ed9da3a16403cf8f040262d73f/packages/compiler-core/src/parser.ts#L1032-L1068","documentation":"Thrown by @vue/compiler-core's parser only in browser builds (__BROWSER__ true, not __TEST__) when the decodeEntities option is missing. In a browser there is no Node.js entity decoder, so the parser needs an explicit function to decode HTML entities (named, decimal, and hex). The guard at parser.ts:1050 deliberately hard-fails rather than silently producing malformed output. The inverse non-browser branch only warns if decodeEntities is passed pointlessly.","triggerScenarios":"Calling parse()/baseParse()/compile() from a browser-targeted build of @vue/compiler-core without supplying options.decodeEntities. Importing the browser ESM entry (e.g. @vue/compiler-core/dist/compiler-core.esm-browser.js) and compiling a template directly.","commonSituations":"Bundling a custom in-browser template compiler and forgetting the decodeEntities callback; upgrading compiler-core to a version that made the option mandatory; using the browser build where previously the Node build was pulled in by the bundler.","solutions":["Pass a decodeEntities function in the compiler options, e.g. decodeEntities from the he package or a shared parserDecodeOptions with @vue/shared's decodeHtml.","If you do not actually need browser compilation, import the Node/CJS build of @vue/compiler-core instead of the *-esm-browser entry so the guard's __BROWSER__ branch is not compiled in.","For library authors wrapping the compiler, reuse the decodeEntities option that @vue/compiler-sfc and @vue/compiler-dom already wire up rather than building your own.","During testing set __TEST__ (the vitest define) so the guard is skipped, only if you are intentionally testing parser internals."],"exampleFix":"// before (browser build)\nimport { baseParse } from '@vue/compiler-core'\nconst ast = baseParse('<div>&amp;</div>')\n\n// after\nimport { baseParse } from '@vue/compiler-core'\nimport { decodeHtml } from '@vue/shared'\nconst ast = baseParse('<div>&amp;</div>', {\n  decodeEntities: (text, asAttr) => decodeHtml(text, asAttr),\n})","handlingStrategy":"validation","validationCode":"// Before calling baseParse/compile in a browser build, ensure decodeEntities is set.\nimport { baseParse } from '@vue/compiler-core'\nimport { decodeHtml } from '@vue/shared'\n\nfunction safeParse(source: string, opts: Record<string, unknown> = {}) {\n  if (!opts.decodeEntities) {\n    opts.decodeEntities = (text: string, asAttr: boolean) => decodeHtml(text, asAttr)\n  }\n  return baseParse(source, opts as any)\n}","typeGuard":"function hasDecodeEntities(opts: unknown): opts is { decodeEntities: (t: string, a?: boolean) => string } {\n  return !!opts && typeof (opts as any).decodeEntities === 'function'\n}","tryCatchPattern":null,"preventionTips":["Default decodeEntities whenever you wrap the compiler in a browser context.","Confirm which entry (esm-browser vs cjs) your bundler resolves before shipping browser-side compilation.","Reuse the decodeHtml helper from @vue/shared so named, decimal, and hex entities are all covered."],"tags":["vue","compiler-core","browser-build","html-entities","configuration"],"backgroundTag":null,"analyzedSha":"a2b40db9a83b36ed9da3a16403cf8f040262d73f","analyzedAt":"2026-08-12T14:21:14.989Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}