> ## Documentation Index
> Fetch the complete documentation index at: https://hyperlocalise.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Localize HubSpot

> Import HubSpot emails, forms, blog posts, landing pages, and website pages, translate them in Jobs, and push locale copies.

Hyperlocalise translates the copy. HubSpot does not. Import reads primary marketing emails, forms, blog posts, landing pages, and website pages. **Push to HubSpot** creates separate locale copies and leaves the source object unchanged. Nothing is published or sent.

## Prerequisites

| Requirement | Description |
| - | - |
| Native project | A [native project](https://hyperlocalise.dev/platform/projects/create-project.md) whose source locale matches the language of the HubSpot source. Add a project target locale for each language you will push back. |
| HubSpot account | Connect HubSpot from **Integrations**. The authorization needs scopes `content` and `forms`. `content` covers marketing emails, blog posts, landing pages, and website pages. `forms` covers forms. |
| Locale mapping | HubSpot language codes are lowercase, with a hyphen when they include a region (`fr`, `fr-ca`, `pt-br`, `en-gb`, `zh-cn`). `fr` and `fr-ca` stay different languages. A project tag such as `fr-FR` maps to `fr` when HubSpot has no `fr-fr` code. The locale copy keeps the full tag in its name (`Welcome [fr-FR]`). |

## Connect HubSpot

Open **Integrations** and choose **Connect** on **HubSpot**. Authorize the HubSpot account in the window that opens. The connection uses the existing `hubspot` WorkOS Pipes provider. The token is not stored in Hyperlocalise. The marketplace app source is in `apps/hubspot-app`.

## Translate HubSpot content

Add the **Translate HubSpot content** template from **Popular** or **Marketing**. It is mutually exclusive with Braze, Customer.io, and Loops. Choose the native project, then activate the automation.

On the HubSpot tool, tick the emails to translate. Nothing is imported until at least one email is ticked. Locale copies stay out of the tree. Set **Existing HubSpot translations**: **Only empty locales** (default), **Refresh imported locales**, or **Overwrite all locales**. **Overwrite HubSpot copies when the remote copy is newer** is on by default. Uncheck it to keep copies that teammates edited after the last push.

A scheduled or manual run imports content. It does not push. Push runs only when you choose **Push to HubSpot** in the Content editor.

## What import writes

Import reads primary objects and writes source files:

* Marketing emails at `hubspot/emails/{id}/{slug}.html`, with the subject, preview text, and translatable widget fields
* Forms at `hubspot/forms/{id}/{slug}.json`, with labels, placeholders, help text, submit text, and legal copy
* Blog posts at `hubspot/blog-posts/{id}/{slug}.json`, with the title, meta description, summary, post body, and section text
* Landing pages at `hubspot/landing-pages/{id}/{slug}.json`, with the title, meta description, image alt text, and translatable widget and layout fields
* Website pages at `hubspot/website-pages/{id}/{slug}.json`, with the same fields as landing pages

When a blog post, landing page, or website page has no saved module edits, import reads that template and included sections. The default copy the editor shows is imported from there. A blog post that already has an article body still picks up section text from its layout or template. Push writes the translation onto the locale draft and leaves the template unchanged.

Import skips blog posts, landing pages, and website pages that are already language variations, and names that already look like locale copies (`Welcome [fr-FR]`). Field names, widget ids, URLs, and colors stay locked. Import does not write anything to HubSpot.

A later import still checks mapped target locales when the source has not changed. If HubSpot already has a locale copy or language variation, import can seed that copy as an approved translation. **Only empty locales** never overwrites work already in Hyperlocalise.

When **Create native TMS job** is enabled, the run opens a job for mapped locales that still need translation. Locales just seeded from HubSpot are left out.

A project locale maps to a HubSpot code in this order:

1. The same code, lowercased, with `_` written as `-` (`pt-BR` becomes `pt-br`).
2. A short list of aliases HubSpot uses: `zh-CN` becomes `zh-cn`, `zh-TW` becomes `zh-tw`, `he` becomes `he-il`, and Norwegian tags become `no-no`.
3. The language alone, when HubSpot accepts that language and has no matching regional code (`fr-FR` becomes `fr`).

When two project locales become the same HubSpot code, the second locale is skipped. The source object's language must match the project source locale. An empty object language is treated as a match.

## What push writes

1. Translate and [approve](https://hyperlocalise.dev/platform/cat.md) the mapped locales you want to write back.
2. In the Content editor, choose **Push to HubSpot** and select the mapped items.

Push creates a copy named `{source} [{locale}]`, for example `Welcome [fr-FR]`. A later push updates that copy instead of creating another one.

| Surface | What lands in HubSpot |
| - | - |
| Marketing email | A cloned email, then a draft with the target language and the translated subject, preview, and widgets. The source email stays as it was. |
| Blog post | A language variation of the primary post, with the translated title, meta description, summary, body, and section text on the draft. The post stays unpublished. If the blog itself has no variation for that language, push creates that blog variation first. |
| Landing page | A language variation of the primary landing page, with the translated title, meta description, alt text, widgets, and layout on the draft. The page stays unpublished. |
| Website page | A language variation of the primary website page, with the same draft fields as a landing page. The page stays unpublished. |
| Form | A new form with the translated labels and HubSpot's built-in messages for that language. The source form stays on any page that already embeds it. The new form exists in the portal and is not embedded for you. |

HubSpot's own translate actions are not used. Hyperlocalise writes the approved strings onto the copy.

A later push skips a locale whose approved content already matches the last successful push. **Only empty locales** pushes only to copies that carry no locale content yet, so it never overwrites a copy that already holds translations. **Refresh imported locales** pushes a locale again only when its approved content changed since the last push.

## Change or remove access

Disconnect HubSpot from **Integrations** to stop this workspace using that account. Inspect automations that depend on the connection before you disconnect.

## If import or push does not run

* Confirm HubSpot is connected and the automation is **Active**.
* Confirm the HubSpot authorization still has `content` and `forms`.
* Confirm the project source locale matches the language of the HubSpot source.
* Confirm each target locale maps to a HubSpot language the account has enabled.
* Open **Run History** for the failed item or locale.

See [Automation troubleshooting](https://hyperlocalise.dev/platform/help/automations.md) and [Connection troubleshooting](https://hyperlocalise.dev/platform/help/connections.md).

## Known limitations

| Content | Status |
| - | - |
| Emails | Supported |
| Forms | Temporarily unsupported |
| Blog posts | Temporarily unsupported |
| Landing pages | Temporarily unsupported |
| Website pages | Temporarily unsupported |

Import skips unsupported content, and it does not appear in **Content to translate**. The in-app email preview shows the imported copy in a generic layout, not the HubSpot design.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.