# Understand additional syntax for creating custom components

[BetaThis feature is new and we're actively working on it.](/beta-experimental-features/#beta-features)

In Design Studio, there are a number of top-level elements available in a custom component file as well as other syntax.

 Use our Design Studio GPT to create a custom component!

[Learn how to best utilize our GPT](/journeys/create-custom-component/#design-studio-gpt) to create code for reusable, custom content.

## Required top-level syntax[](#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](/journeys/component-slots/) - a way to make certain content editable in the visual editor
*   Declare and validate [properties](/journeys/component-properties/)
*   Set [context](#pass-data-to-nested-components-with-context) for use in any child components
*   Define [component configuration](#config) 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](#insert-dynamic-values)
*   Set [directives](/journeys/directives/)
*   Create [`<fragment>` tags](#fragments) to add logic without unneeded HTML

## Optional top-level syntax[](#optional-top-level-syntax)

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

*   [`<style>`](#style)
*   [`<title>`](#title)
*   [`<meta>`](#meta)
*   [`<link>`](#link)

You can also set [directives](/journeys/directives/) in these tags.

### `style`[](#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](/journeys/component-styling/) for more.

### `title`[](#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`[](#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.

```html
<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.

### `link`[](#link)

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.

```html
<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[](#config)

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.

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

## Pass data to nested components with `context`[](#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.

```html
<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.

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

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

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

## Fragments: add logic without extra HTML[](#fragments)

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.

```html
<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.

```html
    <fragment :html="myHTMLVariable" />
```

## Insert dynamic values[](#insert-dynamic-values)

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

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

To support injecting arbitrary content inside a component, you can use [slots](/journeys/component-slots/).

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

## Comments[](#comments)

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

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

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

```javascript
// I'm a standard JavaScript comment.
```

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

```css
/* This is a standard CSS comment */
```

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

```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.