# API Use the Maizzle API to compile a string to an HTML email. ## Example ```js [app.js] import { render } from '@maizzle/framework' import tailwindcssPresetEmail from 'tailwindcss-preset-email' let input = `--- title: Hello, world! ---
{{ page.title }}
` const { html } = await render(input, { css: { inline: true, purge: true, shorthand: true, tailwind: { presets: [tailwindcssPresetEmail], content: [ { raw: input, extension: 'html' } ] } } } ) console.log(html) ``` Your `html` string must include at least `` inside the ``, otherwise no CSS will be output or inlined. Notice also the `css.tailwind` config. The `content` key is needed for Tailwind to know where to look for classes to generate - otherwise your `
Test
` const { html } = await render(input, { css: { tailwind: { presets: [tailwindcssPresetEmail], content: [ { raw: input, extension: 'html' } ] } } }) ``` In order for Tailwind to actually generate CSS based on classes in your `input` string, you need to pass the `content` key with an array of objects that contain the raw content and the file extension. ## Templating Of course, templating tags are available when using Maizzle programmatically. ```js [app.js] let html = `--- title: Using Maizzle programmatically --- ` ``` ::alert{type="danger"} Paths to Layouts or Components in your string must be relative to the location where you execute the script. :: ::alert{type="danger"} Component `x-` tags only work in Node.js and when the referenced files are available on disk. :: ## Gotchas Since the options object that you can pass to the `render` method is optional, there are a few gotchas that you need to be aware of. ### Tailwind config Maizzle will use the Tailwind CSS config object as-is, which means that if you just include the `content` key it will generate CSS with the default values like `rem` or CSS variables. In order to generate CSS optimized for HTML email, you need to fully configure Tailwind in the `css.tailwind` object. The simplest way to do this is to use a preset like `tailwindcss-preset-email`, as shown in the example above. ### Default Tailwind If you don't specify a [Tailwind config object](https://maizzle.com/#tailwindcss), Maizzle will try to compile Tailwind using `tailwind.config.js` at your current path. *If the file is not found, Tailwind CSS will be compiled with its [default config](https://github.com/tailwindlabs/tailwindcss/blob/master/stubs/config.full.js){rel=""nofollow""}.* The default config is not optimized for HTML email: it uses units like `rem` and CSS properties that are used for *web* design and which have little to no support in the majority of email clients. Also, the default Tailwind config will not include any `content` paths that should be scanned for generating utility classes, meaning that the ` /* [!code ++] */ ... ``` # Asset Files Any files that you add to your [content sources](https://maizzle.com/docs/configuration/build#content) will be copied over to the root of the build destination directory, so you can organize your email templates as needed. ## Global assets You may define a global email assets folder that will be copied to the build directory. The Starter sets it to the `images` directory: ```js [config.js] export default { build: { static: { source: ['images/**/*'], destination: 'images', } } } ``` Everything inside `static.source` will be copied to the `static.destination` directory, which is relative to [`build.output.path`](https://maizzle.com/docs/configuration/build#path). ## Multiple sources You may define multiple asset source paths and all files from those paths will be copied to a single destination directory: ```js [config.js] export default { build: { static: { source: ['images/**/*', 'fonts/**/*'], destination: 'assets' } } } ``` # Build process When you run `maizzle build`, your Templates go through a series of events that compile them to plain HTML and apply various, email-specific transformations. To get a better understanding of how Maizzle builds your emails, here's a step-by-step guide of what's going on under the hood. ## Environment config First, a global configuration object is computed by merging your Environment config on top of the base `config.js`. For example, running `maizzle build production` will tell Maizzle to look for the `config.production.js` file at your current location, and merge it on top of `config.js`. When running `maizzle build` or `maizzle serve`, only the base `config.js` will be used. ## beforeCreate() The [beforeCreate](https://maizzle.com/docs/events#beforecreate) event (CLI-only) is triggered, giving you access to the config before Maizzle loops over your Templates to compile them. ## Clean destination The destination directories that you have defined under `build.output.path` in your environment config are deleted. ::alert{type="warning"} Be careful when customizing this path, so you don't end up deleting important directories and files on your machine. :: ## Compile templates Each Template file is parsed and compiled: 1. Maizzle reads the Template file 2. It extracts its Front Matter 3. A unique Template `config` is computed by merging the Template's Front Matter keys with the Environment `config` 4. [beforeRender()](https://maizzle.com/docs/events#beforerender) event is triggered 5. The HTML is rendered with PostHTML :br:br Your Environment name and all `config` options (including any you defined in Front Matter) are exposed under the `page` object, which you can access through [expressions](https://maizzle.com/docs/expressions). :br:br PostHTML plugins that are used as part of the rendering process: - envTags - core plugin that enables [``](https://maizzle.com/docs/tags#env) tags - envAttributes - core plugin that enables attributes like `src-{env}` - expandLinkTags - core plugin that expands local [`` tags](https://maizzle.com/docs/layouts#link-tag) into ` ``` ::alert{type="danger"} `stack` and `push` tags require a non-empty `name` attribute. :: You may then push content to that stack from a Template: ```html [emails/example.html] {% capture email_title %} Your shopping cart is waiting for you {% endcapture %} ``` Result: ```html [build_production/example.html] {% capture email_title %} Your shopping cart is waiting for you {% endcapture %} ``` ### once You may use the `once` attribute on the `` tag to only push content once in a rendering cycle. This is useful if you're rendering the Component in a loop and want to make sure the contents of `` is only rendered once. For example, imagine this Card Component: ```html [components/card.html]
``` Looping over this Component will only push that CSS once to the `head` stack: ```html [emails/example.html] ``` ## Props Props are attributes that can be added to a Component's tag. They can be used to pass data to the Component, or to configure its behavior. To use props in a Component, you need to define them first. This is done by adding a `
{{ title }}
``` ::alert{type="warning"} Only CommonJS syntax with `module.exports` is currently supported in Components. :: Props that you pass to the Component will be available in the ` ``` ```html [emails/example.html] {2} diff // [!code --] // [!code ++] ``` Alternatively, you may change the prop attribute name to something other than `src`: ```js [config.js] export default { components: { attribute: 'href', }, } ``` ### Encoding props data When passing a props object to a Component, you need to encode the values. For example, these won't work: ```html ``` ```html ``` But this will: ```html ``` ### Aware props By default, props are scoped to the Component and are not available to nested Components. If you need to change this, you may use the `aware:` prefix when passing props to a Component: Consider the following two Components: ```hbs [components/child.html]
Title in child: {{ title }}
``` ```hbs [components/parent.html]
Title in parent: {{ title }}
``` If you pass the `title` to the `x-parent` Component: ```html [emails/example.html] ``` ... the result will be: ```html [build_production/example.html]
Title in parent: Hello, world!
Title in child: Default child title
``` As you can see, the `title` prop was not passed down to the `x-child` Component, and it used the default value instead. To make sure a prop is passed down to all nested Components, use the `aware:` prefix: ```html [emails/example.html] ``` Now you'll see the result that you'd expect: ```html [build_production/example.html]
Title in parent: Hello, world!
Title in child: Hello, world!
``` ## Attributes You may pass HTML attributes to a Component and they will be added to the root element of the Component. If you want to change the element to which the attributes are added, you can use the `attributes` attribute: ```html [components/example.html]
``` ### Expressions in attributes [Expressions](https://maizzle.com/docs/expressions) may be used in a Component's attribute: ```hbs [emails/example.html] --- title: "Hello, world!" --- ``` ### Attribute removal The following attributes will be removed from the target element: - unknown HTML attributes (see [valid-attributes.js](https://github.com/thewebartisan7/posthtml-components/blob/main/src/valid-attributes.js){rel=""nofollow""}) - attributes that are defined as props in the Component ### Attribute merging `class` and `style` attribute values will be merged with existing ones from the target element. All other attributes will be overwritten. ### Safelist attributes If you need to safelist or even block certain HTML attributes that you pass to a Component, see the [Component configuration docs](https://maizzle.com/docs/configuration/components#elementattributes). ## Variables When creating a Component, you have access to global `page` variables: ```hbs [components/example.html]
Building for: {{ page.env }}
``` Using this `` Component in a Template will render: ```html [build_production/example.html]
Building for: production
``` # Button Component The Button component makes it easy to add a styled link button to your HTML emails. ## Usage The Button component is defined in `components/button.html`. This enables the `` tag, which you can use like this: ```html [emails/example.html] Book now ``` You can use it anywhere you'd use a `
`. ## Customization You can align the Button to the left, center or right, change its CSS styling, and adjust padding for Outlook on Windows. ### Href Default: `undefined` If you want the Button to link somewhere, you need to pass it the `href` prop: ```html [emails/example.html] Book now ``` ::alert The Button still renders if you don't pass `href` , but it will not include the `href` attribute on the `` tag and might look broken in some email clients because of this. :: ### Align Default: `undefined` You can align the Button to the left, center or right, through the `align` prop: ```html [emails/example.html] Book now ``` This will add the `text-center` class to the button's wrapper `
`, which will align the `` inside it to the center. ### Styling You may style the Button as needed through props or with Tailwind CSS utilities. The button includes a [[]{.w-3.h-3.bg-indigo-700.rounded class="mt-1.5" title="#4338ca"}[bg-indigo-700]{.text-sm/6}]{.inline-flex.gap-1.px-2.border.border-slate-200.border-solid.rounded class="translate-y-0.5"} background and [[]{.w-3.h-3.border.border-solid.rounded.bg-slate-50 class="mt-1.5" title="#f8fafc"}[text-slate-50]{.text-sm/6}]{.inline-flex.gap-1.px-2.border.border-slate-200.border-solid.rounded class="translate-y-0.5"} text color by default, which you can change through props. For example, let's make the button blue-themed: ```html [emails/example.html] Book now ``` You can also use Tailwind CSS utilities to set the text and background colors: ```html [emails/example.html] Book now ``` Of course, you may also change the colors directly in `components/button.html`. ### MSO Padding Top and bottom padding for Outlook on Windows is controlled through `letter-spacing` and `mso-text-raise`, a proprietary Outlook CSS property. This technique is based on the Link Button from [goodemailcode.com](https://www.goodemailcode.com/email-code/link-button){rel=""nofollow""}. #### MSO top padding Default: `16px` Adjust the top padding for Outlook on Windows with the `mso-pt` prop: ```html [emails/example.html] Book now ``` #### MSO bottom padding Default: `31px` Adjust the bottom padding for Outlook on Windows with the `mso-pb` prop: ```html [emails/example.html] Book now ``` ### Other attributes You may pass any other HTML attributes to the component, such as `data-*` or `id` - they will all be added to the `` tag. Note that non-standard attributes will be ignored by default - you'll need to define them as props in the component if you need them preserved. Alternatively, you can [safelist](https://maizzle.com/docs/configuration/components#safelistattributes) them in your `build.components` config. ## Responsive To override Button styling on small viewports, use Tailwind CSS utilities. For example, let's make the button full-width on small viewports: ```html [emails/example.html] Book now ``` ## Alternatives There are other ways to create buttons in your HTML emails, such as by using a ``. Check out our [Button examples](https://maizzle.com/docs/examples/buttons) for more ideas. # Divider Component Quickly add horizontal visual dividers to your HTML emails. ## Usage The Divider component is defined in `components/divider.html`. This enables the `` syntax, which you can use like this: ```html [emails/example.html] {5}
``` You can use it anywhere you'd use a `
`. Simply using the `` tag will render a `1px` gray horizontal line with `24px` of space above and below it. ## Customization You can customize the Divider and give it a custom height (line thickness), change its color, and adjust the space around it. ### Height Default: `1px` The default height is `1px`, but you can change it with the `height` prop: ```html [emails/example.html] ``` ### Color Default: `#cbd5e1` Define a custom line color with the `color` prop. You can use any CSS color value. If you omit this prop, the Divider will use `bg-slate-300` from Tailwind CSS, which is currently set to `#cbd5e1`. Let's change the color to red: ```html [emails/example.html] ``` You can also use Tailwind CSS utilities if you prefer: ```html [emails/example.html] ``` ::alert Tailwind CSS utilities must be passed inside the `class` attribute, not the `color` attribute. :: ### Margins Default: `undefined` Add margins to any of the four sides of the Divider, through these props: - `top` - `right` - `bottom` - `left` For example, let's add `32px` to the top and `64px` to the bottom: ```html [emails/example.html] ``` Under the hood, the CSS `margin` property is used, so you can use any CSS unit that is supported in HTML emails. ::alert Margin props will override `space-y|x` props. :: ### Spacing Default: `24px|undefined` You may add top/bottom or left/right spacing through a single prop: - `space-y` for top & bottom (default: `24px`) - `space-x` for left & right (not set by default) For example, let's add `32px` to the top and bottom: ```html [emails/example.html] ``` Similarly, let's add `24px` to the left and right: ```html [emails/example.html] ``` ::alert `space-y|x` props will be overridden by individual margin props. :: ### Other attributes You may pass any other HTML attributes to the component, such as `data-*` or `id`. Note that non-standard attributes will be ignored by default - you'll need to define them as props in the component if you need them preserved. Alternatively, you can safelist them in your `build.components` config. ## Responsive To override Divider styling on small viewports, use Tailwind CSS utilities: ```html [emails/example.html] ``` ## Outlook note The root `
` element of the Divider component needs some extra attention for Outlook on Windows, otherwise it will render thicker than intended. For the Divider to render the visual line as expected in Outlook on Windows too, it should also be styled with `mso-line-height-rule: exactly`. In Maizzle, this is set globally in the `main.html` layout so you don't need to worry about it. However, if you can't use that layout for some reason or are worried that the Outlook-specific CSS in the `` might be stripped in some situations, simply add it in a style attribute on the tag: ```html [emails/example.html] ``` Alternatively, you may also use the `mso-line-height-rule-exactly` class that is available from the `tailwindcss-mso` plugin (included in the Starter): ```html [emails/example.html] ``` Of course, you can also modify `components/divider.html` and add the `mso-line-height-rule: exactly` CSS rule to the `
` element. ## Alternatives There are other ways to create horizontal visual dividers in your HTML emails, such as using a `` or an `
`. Check out our [Divider examples](https://maizzle.com/docs/examples/dividers) for more ideas. # Spacer Component The Spacer component in Maizzle makes it super simple to add consistent, accessible vertical spacing to your HTML emails. ## Usage The Spacer component is defined in `components/spacer.html`. This enables the `` syntax, which you can use like this: ```html {5}
``` You can use it anywhere you'd use a `
`. If you need to add space between ``, see the [Row Spacer example](https://maizzle.com/docs/examples/spacers#row) instead. ## Props You can pass props to the component via HTML attributes, to control its height. ### height Default: `undefined` This will define the height of the Spacer. You may use any CSS unit that you prefer, it doesn't have to be `px`. ```html [emails/example.html] ``` That will render the following HTML: ```html [emails/example.html]
‍
``` If `height` is omitted, the Spacer will render as `
‍
`, which will render as an empty space that is as high as its parent element's `line-height`. ### mso-height Default: `undefined` Override the height of the Spacer in Outlook for Windows. ```html [emails/example.html] ``` This uses the `mso-line-height-alt` MSO CSS property to set a custom Spacer height in Outlook for Windows. Note: for the Spacer to work as expected in Outlook on Windows, it should also be styled with `mso-line-height-rule: exactly`. In Maizzle this is set globally in the `main.html` layout, so you don't need to worry about it. However, if you can't use that layout for some reason or are worried that the Outlook-specific CSS in the `` might be stripped in some situations, simply add it in a style attribute on the tag: ```html [emails/example.html] ``` Alternatively, you may also use the `mso-line-height-rule-exactly` class that is available from the `tailwindcss-mso` plugin (included in the Starter): ```html [emails/example.html] ``` Of course, you can also modify `components/spacer.html` and add the `mso-line-height-rule: exactly` CSS rule to the `
` element. ### Other attributes You may pass any other HTML attributes to the component, such as `class` or `id`. Note that non-standard attributes will be ignored by default - you'll need to define them as props in the component if you need them preserved. Alternatively, you can safelist them in your `build.components` config. ## Responsive To override the height of the Spacer on mobile, use the `leading` utilities in Tailwind CSS: ```html [emails/example.html] ``` # VML Components VML stands for Vector Markup Language, it is a legacy markup language that was used in Outlook for Windows. The Maizzle Starter includes a VML component that you can use to add support for background images in Outlook for Windows. ## v-fill The Fill component is defined in `components/v-fill.html`. Use it when you need to add a background image that you don't know the height of. ::alert{type="warning"} `v:fill` does not work in Windows 10 Mail. :: You can use it immediately inside a container that has a CSS background image: ```html {4-9}
// [!code ++] HTML to show on top of the image // [!code ++]
``` That will compile to: ```html {4-9}
HTML to show on top of the image
``` ## Props The `x-v-fill` component supports the following props: ### image Default: `https://via.placeholder.com/600x400` The URL of the image that will be used as a background image in Outlook for Windows. ### width Default: `600px` The width of the image, preferably in pixels. This sets CSS `width` on the root `` VML element of the component, so you'll need to include the unit, i.e. `600px` instead of `600`. ### inset Default: `0,0,0,0` Replicates the CSS `padding` property. The order of the values is `left, top, right, bottom`. This is applied to a `` element that wraps the content of the component - basically, the content that you want overlayed on top of the background image. ```html ``` ### type Default: `frame` The type of fill to use. You can use `frame` or `tile`. ### sizes Default: `undefined` Define the exact dimensions of the `` element. Both values need to be set and they can be separated by either a comma or a space: ```html ``` ### origin Default: `undefined` Replicates the CSS `background-position` property. ```html ``` TL;DR: - `origin="-0.5,-0.5" position="-0.5,-0.5"` equals `top left` - `origin="0.5,-0.5" position="0.5,-0.5"` equals `top right` - `origin="-0.5,0.5" position="-0.5,0.5"` equals `bottom left` - `origin="0.5,0.5" position="0.5,0.5"` equals `bottom right` Read more [here](https://www.hteumeuleu.com/2021/background-properties-in-vml/#background-position){rel=""nofollow""}. ### position Default: `undefined` See the docs for `origin` above. ### aspect Default: `undefined` Replicates the CSS `background-size` property. Possible values: - `atleast` (background-size: cover) - `atmost` (background-size: contain) Example: ```html ``` ### color Default: `undefined` Replicates the CSS `background-color` property. Example: ```html ``` ### fillcolor Default: `none` Whether to fill the shape with a color. Example: ```html ``` ### stroke Default: `f` Adds a border to the shape. Example: ```html ``` ### strokecolor Default: `undefined` The color of the border. Example: ```html ``` # Build configuration Configure the paths where Maizzle should look for Templates to compile, where they should be output to, or what extensions they should use. This is done under the `build` key of your config: ```js [config.js] export default { build: { content: ['emails/**/*.html'], } } ``` ## content Type: `String[]`:br Default: `['emails/**/*.html']` Define the source directories where Maizzle should look for Templates to compile. This is an array of glob patterns, similar to how content sources are configured in Tailwind CSS. See [fast-glob](https://github.com/mrmlnc/fast-glob){rel=""nofollow""} for how to write glob patterns. The `content` key is unique to each config file - unlike other options in your config, it is not merged when using multiple Environments. This way, we avoid processing unwanted Templates when building for a specific Environment. To illustrate this, imagine this is your `config.js` file: ```js [config.js] export default { build: { content: ['emails/**/*.html'], } } ``` ... and this is your `config.production.js` file: ```js [config.production.js] export default { build: { content: ['emails/transactional/**/*.html'], } } ``` When running `maizzle build production`, only the Templates from the `emails/transactional` folder will be compiled, no matter if the `emails` folder contains other Templates. ### File types Specify which file extensions should be considered when looking for Templates to compile. For example, to include both `.html` and `.blade.php` files: ```js [config.js] export default { build: { content: ['emails/**/*.{html,blade.php}'], } } ``` ### Excluding files You may exclude files from being compiled by prefixing the glob pattern with an exclamation mark `!`. For example, to exclude all files ending in `-ignore.html`: ```js [config.js] export default { build: { content: [ 'emails/**/*.html', '!emails/**/*-ignore.html', ], } } ``` ### Compute paths If you need to compute the content source paths dynamically, you can use a function that returns an array of strings: ```js [config.js] const sources = () => { return ['templates**/*.html', 'amp-templates/**/*.html'] } export default { build: { content: sources } } ``` ::alert Previously this was called 'Function source', and it allowed defining sources as a function that was evaluated by Maizzle. This is deprecated starting with Maizzle 5. :: ### Multiple sources You may define multiple content sources: ```js [config.js] export default { build: { content: [ 'marketing/**/*.html', 'transactional/**/*.html' ] } } ``` ## output Type: `Object`:br Default: `{ path: 'build_[env]', extension: 'html', from: ['emails'] }` Define the output path for compiled Templates, and what file extension they should use. ### path Type: `String`:br Default: `build_[env]` Directory path where Maizzle should output the compiled emails. ```js [config.production.js] export default { build: { output: { path: 'build_production', } } } ``` If you omit this key, a `build_[env]` directory name will be used, where `[env]` is the current environment, i.e. `build_production` or `build_local`. ### extension Type: `String`:br Default: `undefined` Define the file extension - without the leading dot - to be used for the compiled templates. For example, let's output [Laravel Blade](https://laravel.com/docs/8.x/blade){rel=""nofollow""} files: ```js [config.laravel.js] export default { build: { output: { path: 'build_laravel', extension: 'blade.php' } } } ``` The compiled Templates will be output as `build_laravel/*.blade.php`. By default, Maizzle will use the extension of the source file. ### from Type: `String[]`:br Default: `['emails']` Default directories to unwrap when outputting compiled Templates. For example, if you have a Template located at `emails/welcome.html` in your Maizzle project, by default the compiled file will be output as `build_[env]/welcome.html` - the `emails` part of the path is discarded. If you have multiple sources, you can specify additional directories to unwrap: ```js [config.js] export default { build: { content: [ 'emails/**/*.html', 'amp-templates/**/*.html' ], output: { from: ['emails', 'amp-templates'] } } } ``` ::alert You must specify all directories to unwrap when using `output.from` and multiple `build.content` source paths, as this option overwrites the default `[emails]` value. :: In this case, the compiled files will all be output at the root of the `build_[env]` directory. #### \`from\` caveat Templates in Maizzle are processed in the order their source paths are defined in `build.content`, which means files with identical names will be overwritten if they have the same output path as a result of their parent directory being unwrapped. In the `emails` and `amp-templates` example above, if both directories contain a `welcome.html` file, the content of the one in the `amp-templates` directory will overwrite that of the one in the `emails` directory. ## permalink Type: `String`:br Default: `undefined` Use the `permalink` Front Matter key to define a custom output path right in a Template: ```hbs [emails/example.html] --- permalink: output/this/template/here.html --- ``` This will override `output.path` from your config, but only for this Template. You may use both relative and absolute file paths. For example, output one level above project directory: ```hbs [emails/example.html] --- permalink: ../newsletter.html --- ``` Output at a specific system location: ```hbs [emails/example.html] --- permalink: C:/Users/Cosmin/Newsletter/2024/07/index.html --- ``` ::alert{type="warning"} `permalink` must be a *file * path, and can only be used in the Template's Front Matter. Using a directory path will result in a build error. :: ## static Type: `Object`:br Default: `{ source: '', destination: 'assets' }` Source and destination directories for static asset files. At build time, `build.static.destination` will be created relative to `build.output.path`, and files inside `build.static.source` will be copied into it: ```js [config.js] export default { build: { static: { source: 'images/**/*', destination: 'images', } } } ``` If you have multiple static asset directories, define them as an array of objects: ```js [config.js] export default { build: { static: [ { source: 'images/**/*', destination: 'images' }, { source: 'fonts/**/*', destination: 'fonts' } ] } } ``` As you can see, the `build.static` configuration can be used to copy *any* files to the build directory, not just images. ## spinner Type: `String|Object`:br Default: `'circleHalves'` Customize the spinner shown in the console during build. ```js [config.js] export default { build: { spinner: 'dots' } } ``` See the [ora spinners list](https://github.com/sindresorhus/cli-spinners/blob/main/spinners.json){rel=""nofollow""} for available options. ## summary Type: `Boolean`:br Default: `false` Show a summary at the end the build process. A table with the following information will be displayed: - file name - file size - build time You may also enable this option by passing the `--summary` or `-s` flag to the build command. ```sh maizzle build --summary ``` # Components configuration Control where your Components live and how you reference them. ## root Type: `String`:br Default: `'./'` Root path where to look for folders containing component files. ## folders Type: `Array`:br Default: `['components', 'layouts', 'emails']` Folder paths where to look for component files. Relative to `root`. If you keep your components in a different folder, you can add it here: ```js [config.js] export default { components: { folders: ['custom-components'], }, } ``` The paths you defined will be added to the default folders. ## fileExtension Type: `String`|`String[]`:br Default: `'html'` Define the file extension(s) that component files must use. To define multiple file extensions, use an array: ```js [config.js] export default { components: { fileExtension: ['html', 'php'], }, } ``` Any other files will be ignored and not be made available as components. ## tagPrefix Type: `String`:br Default: `'x-'` Prefix string to use for component tags. If you prefer to write `` instead of ``, do this: ```js [config.js] export default { components: { tagPrefix: 'a-', }, } ``` ## tag Type: `String|Boolean`:br Default: `'component'` You may alternatively reference any component using this tag name and passing in the component file path in the `src` prop. By default, this ensures backwards compatibility with the old components system so you can continue to use syntax like `` in your templates. For example, if you prefer to write ``, do this: ```js [config.js] export default { components: { tag: 'module', }, } ``` Set it to `false` to disable this feature and only use `x-` tags. ## attribute Type: `String`:br Default: `'src'` You may define a custom attribute name to use for the `tag`. ```js [config.js] export default { components: { attribute: 'href', }, } ``` You can now use `` in your templates. ## yield Type: `String`:br Default: `'yield'` Name of the tag that will be replaced with the content that is passed to the component. If you want to change it to be `content` as in previous versions of Maizzle, do this: ```js [config.js] export default { components: { yield: 'content', }, } ``` You'd then define a component like this: ```html [components/button.html]
``` ## slot Type: `String`:br Default: `'slot'` Name for the [`slot` tag](https://maizzle.com/docs/components#slots). For example, maybe you want to change this to be `provide`: ```js [config.js] export default { components: { slot: 'provide', }, } ``` You could then use `provide` instead of `slot` when defining a component: ```html [components/footer.html]

© {{ year }}

``` You'd fill `provide` as usual: ```html [emails/example.html]

Some content

``` Result: ```html [build_production/example.html]

© 2023

Some content

``` ## fill Type: `String`:br Default: `'fill'` Name for the [`fill` tag](https://maizzle.com/docs/components#slots). For example, maybe you want to change this to be `inject`: ```js [config.js] export default { components: { fill: 'inject', }, } ``` Given the previous example, you'd now use `inject` instead of `fill` when defining a component: ```html [emails/example.html]

Some content

``` ## slotSeparator Type: `String`:br Default: `':'` String to use as a separator between the `slot` tag and its name. For example, changing it to `@`: ```js [config.js] export default { components: { slotSeparator: '@', }, } ``` You'd then use `` and ``: ```html [emails/example.html] ``` ## push Type: `String`:br Default: `'push'` Name for the [\ tag](https://maizzle.com/docs/components#stacks). ## stack Type: `String`:br Default: `'stack'` Name for the [\ tag](https://maizzle.com/docs/components#stacks). ## propsScriptAttribute Type: `String`:br Default: `'props'` Name of the props attribute to use in the ` ``` ## propsContext Type: `String`:br Default: `'props'` Name of the object that will be used to store the props of a component. For example, if you change it to `data` like this: ```js [config.js] export default { components: { propsContext: 'data', }, } ``` ... you'd then use `data` instead of `props` when defining the props of a component: ```hbs [components/button.html] ``` ## propsAttribute Type: `String`:br Default: `'locals'` Name of the attribute that will be used to pass props to a component as JSON. Set to `locals` by default, for backwards compatibility with the old components system. Again, let's change it to `data`: ```js [config.js] export default { components: { propsAttribute: 'data', }, } ``` You'd then use `data` instead of `locals` when passing props as JSON to a component: ```html [emails/example.html] Click me ``` ## propsSlot Type: `String`:br Default: `'props'` String value used to retrieve the props passed to slot via `$slots.slotName.props`. For example, if you change it to `data` and have a component with a `header` slot, you'd be able to access the props passed to the slot via `$slots.header.data`. ## parserOptions Type: `Object`:br Default: `{ recognizeSelfClosing: true }` Object to configure the underlying `posthtml-parser` library. By default, it enables support for self-closing component tags. ## expressions Type: `Object`:br Default: `{/*custom object*/}` Object to configure how expressions are handled in components. Maizzle passes your config variables and the contents of your `build.expressions` object to it, so that you have them all available inside your components. ## plugins Type: `Array|Object`:br Default: `[]` Array or object of PostHTML plugins to apply to each parsed component. When used as an array, plugins will be applied to each component *after* expressions are parsed inside of it: ```js [config.js] export default { components: { plugins: [ require('posthtml-example-plugin')(), ], }, } ``` You may use the `before` and `after` keys to apply plugins before or after expressions are parsed: ```js [config.js] export default { components: { plugins: { before: [ require('posthtml-example-plugin')(), ], after: [ require('posthtml-another-plugin')(), ], }, }, } ``` ## attrsParserRules Type: `Object`:br Default: `{}` Extra rules for the PostHTML plugin that is used by components to parse attributes. ## strict Type: `Boolean`:br Default: `true` In `strict` mode, an error will be thrown if a component cannot be rendered. ## utilities Type: `Object`:br Default: `{ merge: _.mergeWith, template: _.template }` Utility methods to be passed to ` {{ foo }} ``` ## removeScriptLocals Type: `Boolean`:br Default: `false` Whether to remove ` ``` ## Template For this tutorial, we'll use the [AMP Carousel](https://amp.dev/documentation/components/amp-carousel/?format=email){rel=""nofollow""} component. Create `emails/amp/carousel.html` and add a basic AMP carousel: ```html [emails/amp/carousel.html]
``` You initialize [AMP components](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-components/?format=email){rel=""nofollow""} by pushing their `