Skip to content

Error: Stateful components cannot contain html, head, or body tags

Taylor Hunt edited this page Sep 1, 2019 · 2 revisions

You will see this error if you have a template that is both a stateful class component and contains <html>, <head>, or <body> elements. Marko does not currently support full-page diffing.

class {
  onCreate() { this.state = { count: 0 } }
  increment() { this.state.count++ }
}

<!doctype>
<html lang="en">
<body>
  <h1>Hello, counter</h1>
  <output>${state.count}</output>
  <button on-click('increment')>++</button>
</body>
</html>

To fix this error, extract the dynamic part to a deeper portion of the tree:

// page.marko
<!doctype>
<html lang="en">
<body>
  <h1>Hello, counter</h1>
  <counter/>
</body>
</html>
// components/counter.marko
class {
  onCreate() { this.state = { count: 0 } }
  increment() { this.state.count++ }
}

<output>${state.count}</output>
<button on-click('increment')>++</button>

You will also see this error if a class component renders another component, and the rendered component has <html>, <head>, or <body> tags. This usually happens with layout components, like so:

// page.marko
class {
  onCreate() { this.state = { count: 0 } }
  increment() { this.state.count++ }
}

<my-layout>
  <h1>Hello, counter</h1>
  <output>${state.count}</output>
  <button on-click('increment')>++</button>
</my-layout>
// components/my-layout.marko
<!doctype>
<html lang="en">
<body>
  <${input.renderBody}/>
</body>
</html>