# Create email content with HTML code editor

<YouTube id="DryThwJHYxk" params="start=258&end=355" playlabel="Youtube Video: Build your email content from scratch with HTML"/>

If you are proficient in HTML and prefer to write your own code, you can create emails using the Pushwoosh HTML code editor.

<Aside type="note">
Don't have coding skills? Use the Drag & drop editor to effortlessly create email content. Zero coding skills required. [Learn more](/product/content/email-content/drag-and-drop-email-editor)
</Aside>

<Aside type="caution" title="Important">
Before you start creating email content, it's essential to properly set up your email within the email editor you choose. This involves configuring languages, specifying the subject line, providing sender information, and more. [Learn how to do it](/product/content/email-content/set-up-your-email-in-the-editor)
</Aside>


## Create email content

To begin creating email content, paste your HTML code into the HTML tab. The editor provides real-time email previews as you are working on them.

<video src="/emails-html-code-editor-1.webm" title="HTML code editor interface showing real-time email preview as code is typed" autoplay loop muted playsinline />

Alternatively, you can upload an HTML file by clicking on **Upload HTML File** located in the bottom panel.

To add a personalized touch to your emails, use custom tags. For this:

1. Click on the **Tag** icon located at the bottom of the editor.
2. Select the desired Tag, and its modifier, and provide a default value if needed.
3. Click **Insert** to include the custom tag in your email content.

<img src="/emails-html-code-editor-2.webp" alt="Custom tag insertion interface showing tag selection and default value options"/>

To include an emoji in your email, click the **Emoji** icon located at the bottom of the editor.

### Add images

To add an image to your email, include an `<img>` tag in your HTML and set the `src` attribute to the image URL.

To reuse an image from your [Media store](/product/content/media-store/), copy its URL there and paste it into the `src` attribute. See [Copy an image URL](/product/content/media-store/#copy-an-image-url) for the steps.

```
<img src="YOUR-MEDIA-STORE-URL" alt="Summer sale banner" width="600" style="display:block;max-width:100%;height:auto;" />
```

Replace `YOUR-MEDIA-STORE-URL` with the URL you copied from the Media store.

## Use localization

Localization empowers you to deliver personalized experiences to users in different languages.

In the HTML code editor, you can use localization by defining a default language and adding multiple language options. For instance, you can set a default message in English and then include translations in German and Spanish. This ensures that your email content adapts to each user's language preferences.

Below is an example of how to structure your localization data. This uses English as the Default language and German and Spanish translations.

```json
{
  "default": {
    "button": "Shop now",
    "description": "For a limited time, you can enjoy a 20% discount on all our premium coffee blends",
    "subtitle": "Don't miss it",
    "title": "☕ Coffee Promotion Alert!"
  },
  "de": {
    "button": "Jetzt einkaufen",
    "description": "Für kurze Zeit erhalten Sie einen Rabatt von 20% auf alle unsere Premium-Kaffeemischungen",
    "subtitle": "Verpassen Sie es nicht",
    "title": "☕ Kaffee-Promotion Benachrichtigung!"
  },
  "es": {
    "button": "Comprar ahora",
    "description": "Por tiempo limitado, puedes disfrutar de un descuento del 20% en todas nuestras mezclas de café premium",
    "subtitle": "No te lo pierdas",
    "title": "☕ ¡Alerta de Promoción de Café!"
  }
}
```

Once your localization data is structured and added in the **Localization Tab** of the editor, incorporate it into your HTML content using placeholders. The placeholders dynamically insert localized text into your content, based on the user's language preference. Here's how to implement it in your HTML

```
{{title|text|}}
{{subtitle|text|}}
{{description|text|}}
{{button|text|}}
```

Consider this scenario: you're advertising a limited-time discount on coffee blends. By using the localization structure mentioned above, you can communicate your promotional message effectively to users speaking different languages. Your HTML code for the promotion might look like this:

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>☕ Coffee Promotion Alert</title>
<style>
  body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 20px;
    background-color: #f4f4f4;
  }
  .container {
    background-color: #fff;
    padding: 20px;
    margin: 10px auto;
    max-width: 600px;
    border-radius: 8px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  }
  .button {
    display: inline-block;
    padding: 10px 20px;
    margin-top: 20px;
    background-color: #ff6f61;
    color: white;
    text-decoration: none;
    border-radius: 5px;
  }
  .button:hover {
    background-color: #ff5733;
  }
  .footer {
    text-align: center;
    margin-top: 20px;
    font-size: 0.8em;
    color: #888;
  }
</style>
</head>
<body>
  <div class="container">
    <h1>{{title|text|}}</h1>
    <p>{{description|text|}}</p>
    <a href="https://www.example.com/promotion" class="button">{{button|text|}}</a>

  </div>
</body>
</html>
```

With this setup, if a user's language is German, they'll see the email in German. Users who opted to receive emails in English will see it in English. Those who opted to receive it in Spanish will receive it in Spanish. This ensures that all recipients get your message in their preferred language.

<video src="/emails-html-code-editor-3.webm" title="Localization demonstration showing email content in different languages" autoplay loop muted playsinline />

## Insert and combine email content blocks

Pushwoosh allows you to combine email content by inserting one piece of email content into another. This makes it easy to reuse elements like headers, footers, or specific content blocks across different emails.

For example, if you have **Email content A** (a header) and **Email content B** (a newsletter), you can insert **Email content A** into **Email content B** without manually copying content each time.

### Syntax

To insert one piece of content into another, use the following syntax:

```
{% email_content "AAAAA-BBBBB" %}
```

Where "AAAAA-BBBBB" is the ID of the email content you want to insert. You can find the ID located beneath the content name in your list of email content.

<img src="/emails-html-code-editor-4.webp" alt="Email content ID display showing content name and unique identifier"/>

<Aside type="caution" title="Important">
* You can insert content recursively, meaning one content block can include another, up to a maximum depth of 3 levels. For example:
  * **Content A** can insert **Content B**.
  * **Content B** can insert **Content C**.
  * However, **Content C** cannot insert another block.
* **Cyclical insertions** (e.g., where **Content A** inserts **Content B** and **Content B** tries to insert **Content A**) are not allowed and will result in an error.
</Aside>  

**Example**

Let’s say you have two pieces of content:

* **Header content** (ID: "AAAAA-BBBBB") with a predefined header design.
* **Newsletter content**, where you want to include the header.

To insert the header into the newsletter, you would use the following:

```

{% email_content "AAAAA-BBBBB" %}
```

This allows you to easily reuse a predefined header in multiple email campaigns. It saves time and ensures consistency across your emails.


## Add an unsubscribe link

Include an unsubscribe link in your email so recipients can opt out in line with regulations and their preferences. Pushwoosh provides three variables you can use in your HTML.

### Unsubscribe link 

Add this link so users can opt out from the message they received:

```
<a href=%%PW_EMAIL_UNSUBSCRIBE%%> Unsubscribe </a>
```

The variable is replaced with the Pushwoosh unsubscribe URL when you send the email.

- When the subscription preference center is enabled, recipients are unsubscribed only from the category assigned to that email (e.g., *Newsletter*). A confirmation screen appears where they can **Resubscribe** to that category or **Manage preferences** to adjust all email categories. [Learn more](/product/messaging-channels/emails/email-preferences/#default-behavior-unsubscribe-from-a-category)

- When the subscription preference center is not enabled, recipients unsubscribe from all marketing emails.

Clicks are counted in the unsubscribe rate for that message in [Message History](/product/statistics-and-analytics/message-history).

### Unsubscribe from all categories 

Add a link that unsubscribes the user from all email categories at once:

```
<a href=%%PW_EMAIL_UNSUBSCRIBE_ALL%%> Unsubscribe from all emails </a>
```

<Aside type="note">
To let you deliver important emails to your customers, we do not delete unsubscribed users from your user base. For users who have fully opted out (for example, via the default unsubscribe link when the preference center is not enabled, or via the Unsubscribe from all link), the [**Unsubscribed Emails** default tag](/product/audience-data-and-segmentation/user-data-tags) is set to 'true'. 

Consider creating a [segment](/product/audience-data-and-segmentation/segmentation/) of users who did not unsubscribe (tag value 'false') to continue messaging them. To avoid complaints, do not email users who have unsubscribed.
</Aside>

### Preference center link 

Add a direct link to the [preference center](/product/messaging-channels/emails/email-preferences/#optional-setup-full-preference-center) where users manage which categories they receive:

```
<a href=%%PW_EMAIL_PREFERENCE_CENTER_LINK%%> Manage preferences </a>
```
[Learn how the preference center works](/product/messaging-channels/emails/email-preferences/#how-to-let-users-unsubscribe-from-a-category-or-manage-preferences)

The screenshot below shows a footer that uses all three link types.

<img src="/emails-html-code-editor-6.webp" alt="Email footer example with all three unsubscribe links: Unsubscribe, Manage preferences, Unsubscribe from all emails"/>

<Aside type="caution">
If you use your own unsubscribe link instead of the Pushwoosh variables, users who opt out via your link are not included in the unsubscribe rate in [Message History](/product/statistics-and-analytics/message-history). Only users who followed the Pushwoosh link are counted in the stats for that email.
</Aside>

## Save email content

After you have finished creating your email, click on the **Save** button located at the top of the editor.

<img src="/emails-html-code-editor-5.webp" alt="Save email content dialog showing name and label fields"/>

In the new window that appears, give your email a clear name, which could be the same as your Subject line. Also, create a label to help you easily find it in your list of emails.

If you haven't [set up sender details](/product/content/email-content/set-up-your-email-in-the-editor) yet, make sure to do that as well. Then, click **Save.**

Now that your email content is ready, it can be used in email campaigns. [Learn more](/product/messaging-channels/emails/sending-emails)

## Send a test email

Before sending your email campaign, you can send a test email to preview how the content will appear in recipients' inboxes. This allows you to review the layout, content, and any personalized elements to ensure accuracy before finalizing the campaign. If needed, adjust the content based on the test results.

<Aside type="note">
If KYC **(Know Your Customer)** is not completed, you can still send test emails by verifying a test email address. To do this, go to the [Test Devices](/developer/first-steps/test-your-integration/test-devices/) section, add the email address you want to use for testing, and complete the verification process.
</Aside>

To send a test email, click **Test email** in the email editor.

<img src="/shared-14.webp" alt="Test email button in email editor interface"/>

 In the window that opens:

1. In the **Email address** field, enter the email address where you want to receive the test email.

If KYC has not been completed, you will need to select a verified email address from the list of test addresses instead of entering an email.

<img src="/shared-50.webp" alt="Verified test email address selection dropdown"/>

2. If your email contains dynamic content (placeholders for personalized data), add sample values for testing purposes.

For example:

* **Age (integer)**: Enter a number to represent the age placeholder (e.g., `21`).
* **FirstName (string)**: Enter a sample first name (e.g., `David`).

These values will replace actual recipient data in the test email, allowing you to verify how the dynamic content appears.

3. Once you've filled in the necessary details, click **Send test email** to send the test message to the provided email address.

<img src="/shared-34.webp" alt="Send test email confirmation dialog with sample data fields"/>