Meituan-Dianping/mpvue · warning

Templates should only be responsible for mapping the state t

Error message

Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <${tag}>, as they will not be parsed.

What it means

Tags with browser side-effects (e.g. <script>, <style>... per isForbiddenTag) are not allowed in templates because templates should only map state to UI. When the parser encounters such a tag outside server rendering, it marks element.forbidden = true so the tag is skipped, and warns in development.

Source

Thrown at packages/weex-template-compiler/build.js:1432

      if (isIE && ns === 'svg') {
        attrs = guardIESVGBug(attrs);
      }

      var element = {
        type: 1,
        tag: tag,
        attrsList: attrs,
        attrsMap: makeAttrsMap(attrs),
        parent: currentParent,
        children: []
      };
      if (ns) {
        element.ns = ns;
      }

      if (isForbiddenTag(element) && !isServerRendering()) {
        element.forbidden = true;
        process.env.NODE_ENV !== 'production' && warn(
          'Templates should only be responsible for mapping the state to the ' +
          'UI. Avoid placing tags with side-effects in your templates, such as ' +
          "<" + tag + ">" + ', as they will not be parsed.'
        );
      }

      // apply pre-transforms
      for (var i = 0; i < preTransforms.length; i++) {
        preTransforms[i](element, options);
      }

      if (!inVPre) {
        processPre(element);
        if (element.pre) {
          inVPre = true;
        }
      }
      if (platformIsPreTag(element.tag)) {

View on GitHub (pinned to 6c5d78ee04)

Solutions

  1. Remove the side-effect tag from the template
  2. Load scripts programmatically (e.g. in mounted()) instead of via <script> in the template
  3. Move styles to a proper style block or CSS file rather than a template <style> tag

Example fix

// before
<template><div><script src="x.js"></script></div></template>
// after
<template><div></div></template>
<script>
export default { mounted() { /* inject script here */ } }
</script>
Defensive patterns

Strategy: validation

Validate before calling

const FORBIDDEN = ['style','script','iframe','video','audio','object','embed','form'];
function hasForbiddenTags(template) {
  return FORBIDDEN.filter(t => new RegExp(`<${t}[\\s>]`, 'i').test(template));
}

Type guard

function isTemplateSafe(template) {
  return typeof template === 'string' && hasForbiddenTags(template).length === 0;
}

Prevention

When it happens

Trigger: Compiling a template containing a forbidden tag (such as <script> or <style>) in a client-side (non-server-rendering) compilation, so isForbiddenTag(element) returns true and warn is configured.

Common situations: Inlining <script> tags in a component template to add tracking code, pasting full HTML pages (with head/script tags) into a component, or trying to load third-party widgets inside a Vue template.

Related errors


AI-assisted analysis of Meituan-Dianping/mpvue@6c5d78ee04 (2026-09-02). Data as JSON: /api/errors/4639a999392a8fd5. Report an issue: GitHub.