Loading…

Understand additional syntax for creating custom components

Design Studio New Updated

This article helps you understand the top-level elements available in a custom component file as well as other syntax.

 This article applies to Design Studio

We are currently piloting Design Studio, our new email design system, and making some information available to customers. If you don’t have access to Design Studio, please continue to use our other email editors.

Required top-level syntax

You must include both <script> and <template> tags in your custom component file.

The <script> tag handles logic, properties, and configuration for the component. In the <script> tag, you can:

  • Write JavaScript logic to help render your <template> HTML. It supports the full JavaScript run-time.
  • Define and validate slots - a way to make certain content editable in the visual editor
  • Declare and validate properties
  • Set context for use in any child components
  • Define component configuration by exporting the config variable

The <template> tag defines the HTML structure and content of the component. In the <template> tag, you can:

  • Add HTML, standard components, and other customer components
  • Reference styles created in the <script> or <style> tags
  • Use JavaScript to create dynamic values
  • Set directives
  • Create <fragment> tags to add logic without unneeded HTML

Optional top-level syntax

We offer four, optional, top-level elements to help you create custom components:

You can also set directives in these tags.

style

<style> tags allow you to add CSS to your component. Pass them to the <template> tag to style your content. Check out our article on stylesheets for more.

title

Add a title to your email. We add the title to the <head> of the message.

If you create multiple, identical titles, we only add one to the <head>.

If you create multiple, non-identical <title> tags, we place all of them in the <head> and let the browser decide which to display.

meta

Add metadata to your email that a browser can read but won’t display for a recipient. This will render in the <head> of the message.

If multiple, identical tags are added, only one is placed in the head.

<meta name="robots" content="noindex" />
<template>This is the component</template>

If you create multiple, non-identical <meta> tags, we place all of them in the <head> and let the browser decide which to use.

You can link to external stylesheets with the <link> tag. This makes it easy to add support for hosted fonts.

If multiple, identical tags are added, only one is placed in the head.

<script>
    const fontFamily = 'Inter'
</script>
<link rel="stylesheet" #set:href="https://fonts.googleapis.com/css?family=${fontFamily}">
<template>
    <p #style:font-family="fontFamily"><slot /></p>
</template>

If you create multiple, non-identical <link> tags, we place all of them in the <head> and let the browser decide if it needs to fetch each one.

Define config to use your component in the visual editor

Use the config variable to define how the component is referenced and export it for use in the visual editor. You must define config as a static object.

<script>
  export const config = { 
    label: "example component",
    presets: [
      {
        label: "example component",
        content: `<example-component></example-component>`
      }
    ]
  }
</script>

Pass data to nested components with context

Set a context to store brand information, color schemes, or user inputs that you want to pass down to nested components. You can pass data down from a grandparent to a grandchild without having to pass properties manually at every level (aka props-drilling). You’d set the context in the highest-level component and get the context in any nested component.

First, call Component.context.set with a key/value or string. All nested components can then use the context as shown below.

<script>
    Component.context.set('theme', {primary: 'blue'});
</script>

Then call Component.context.get in the <script> tag of components you’ll nest inside the one where the context is set. This gives nested components access to the full context.

<!-- <nested component /> -->
<script>
    const inherited_theme = Component.context.get('theme');
</script>

You can access all contexts by simply omitting the context name too.

<!-- <nested component /> -->
<script>
    const all_contexts = Component.context.get();
</script>

Fragments: add logic without extra HTML

Fragments are fake elements. Whereas a <p> tag renders a certain way in an email client, a <fragment> tag wouldn’t display at all. This makes them useful for setting conditionals.

<script>
    const lang = "fr"
</script>
<template>
    <fragment #if="fr">
        <span>Bonjour</span>
    </fragment>
    <fragment #else>
        <span>Hello</span>
    </fragment>
</template>

Above, we used fragments to conditionally render translated content. Note, the directives that set the values of attributes have no effect on <fragment> tags, except when combined with #is.

You can also use the #set:html directive to render HTML defined in the script tag or elsewhere. This is useful if a system might have trouble parsing opening and closing tags.

    <fragment :html="myHTMLVariable" />

Insert dynamic values

Additionally, you can insert full JavaScript expressions inside the content of any HTML using the standard template literal syntax ${}.

<div>${1+2*3/4}</div>

To support injecting arbitrary content inside a component, you can use slots.

<template>
	<a :href="href"><slot>Click me</slot></a>
</template>

Comments

You can add standard HTML comments anywhere within <template>.

<!-- I'm a standard HTML comment -->

In the <script> tag, use standard JavaScript comments.

// I'm a standard JavaScript comment.

In the <style> tag, use standard CSS comments.

/* This is a standard CSS comment */

While standard comments are not evaluated, all conditional comments are processed as normal HTML.

<!--[if mso]><i :style:letter-spacing="`${10*5}px`" hidden>&nbsp;</i><![endif]-->

Note, we compile comments inside the <template> and <style> tags into the final output.

Copied to clipboard!
  Contents
Is this page helpful?