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
- Remove the side-effect tag from the template
- Load scripts programmatically (e.g. in mounted()) instead of via <script> in the template
- 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
- Never inline <script> or <style> in component templates
- Inject third-party scripts from mounted()/plugins instead
- Lint templates with a rule that flags side-effect tags
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
- tag <${tag}> has no matching end tag.
- <template> cannot be keyed. Place the key on real elements i
- Invalid v-for expression: ${exp}
- v-${el.elseif ? ('else-if="' + el.elseif + '"') : 'else'} us
- text "${children[i].text.trim()}" between v-if and v-else(-i
AI-assisted analysis of Meituan-Dianping/mpvue@6c5d78ee04 (2026-09-02).
Data as JSON: /api/errors/4639a999392a8fd5.
Report an issue: GitHub.