Is it possible to configure prettier to treat text within a script tag as HTML?

Viewed 276

I'm using Vue, and I write many of my templates inside a script tag. I'd like to configure Prettier to treat those templates as the HTML that they are, but I haven't found anything in the documentation about how to do this.

It looks something like this. Right now, Prettier doesn't help me with the HTML inside that script tag. I'd like to tell it that these contain HTML so it behaves as it would if that HTML were outside the script tag.

<script type="text/x-template">
  <p>Hello world.</p>
</script>

Aside... I rely so heavily on Prettier that I am putting the HTML inside the script tags in a partial so it can be in a separate file where Prettier will run on it. Convoluted, but it's a workaround. Still, I really want a solution for this.

2 Answers

Prettier doesn't support this right now, but might support in the future if somebody crafts a PR. The closest thing that you can do now is to use type="text/x-handlebars-template", but this won't use the same parser and printer that is used for HTML. Handlebars (Glimmer) support is still alpha.

One alternative is to use <template> tags instead of <script type="text/x-template">:

<template id="my-component-template">
  <p>Hello world.</p>
</template>

Browsers will not render the <template> tag, but Prettier will recognize and format it as regular HTML.

This should not be confused with how <template> tags are often used for wrapping multiple elements inside Vue directives (v-if and v-for). In fact, you can mix both:

<template id="my-component-template">
  <div class="my-component">
    <template v-if="sayHello">
      <div>Hello</div>
      <div>world!</div>
    </template>
    <div v-else>Good bye</div>
  </div>
</template>

The outermost <template> serves as a container for the Vue template, and the inner ones are used for control flow.

(This is similar to how Single File Components are organized, by the way.)

Caveats

Browsers will parse the contents of <template> tags as regular HTML markup and attempt to correct "bad" HTML. So this:

<template id="my-component-template">
  <table>
    <another-component></another-component>
  </table>
</template>

...will be "corrected" to:

<template id="my-component-template">
  <another-component></another-component>
  <table></table>
</template>

For details, check out DOM Template Parsing Caveats (or the v2 docs) in the official Vue docs.

Related