If you work with multilingual SharePoint sites, you know the pain.

Modern pages are easy to create… until you need them in Dutch + French (or more) and you want:

  • the title translated,
  • the actual page content translated (not just a copy),
  • the translation pages published automatically,
  • and all of that without manual copy/paste or people forgetting steps.

SharePoint has multilingual pages, yes. But keeping them consistently updated is where the real work starts.

In this post I’ll walk through a Power Automate flow that automates the full cycle:

  • detect when a page is updated (major version)
  • create translation pages
  • translate CanvasContent1 (HTML blocks) + the Title
  • save as draft + publish
  • clean up older translation versions

The real problem: translation isn’t just “create a page”

The default multilingual experience helps you create translations, but it doesn’t solve:

  • content authors updating the original page and forgetting to update translations
  • translations drifting over time
  • publishing steps being missed (draft translations)
  • inconsistent authoring metadata
  • clutter from old translation pages/versions

The goal of this flow is simple:

Every time the source page gets a new major version, translations should be recreated/updated and published — automatically.

⚙️ Prerequisite: Azure Translation Service (don’t skip this)

Before this flow will work reliably in production, you must set up the Azure Translation Service.
Power Automate does not magically translate HTML content by itself — it relies on Azure AI Translator under the hood.

This is not optional for this solution.

Why Azure Translation is required

This flow translates:

  • page titles
  • HTML content inside CanvasContent1
  • structured text blocks that must preserve layout and formatting

That means:

  • plain text translation connectors are not enough
  • HTML-aware translation is required
  • translation quality and performance must be predictable

Azure AI Translator gives you:

  • HTML-safe translation
  • language auto-detection
  • governance and cost control
  • a stable backend for Power Automate connectors

What exactly is used in this flow

Depending on the language branch, the flow uses:

  • Microsoft Translator connector
  • Translator V2 connector
  • AI Builder – Text Translation (prebuilt model)

All of these rely on Azure AI Translator being correctly configured.

If Azure Translator is missing or misconfigured:

  • translations will fail silently
  • flows will partially succeed (worst case)
  • HTML content may break or return empty results

Learn more about Azure Translation service: https://learn.microsoft.com/en-us/azure/ai-services/translator/solutions/connector/document-translation-flow?tabs=blob-storage

What the flow does (high-level)

When a Site Page is modified, the flow:

  1. Runs only for major versions (e.g. 3.0, 4.0)
  2. Skips translation pages (prevents looping)
  3. Loads the source page’s CanvasContent1 + Language
  4. Creates translation pages via SharePoint REST
  5. For each translation page:
    • resolves the Page ID
    • translates title
    • translates HTML blocks inside CanvasContent1
    • saves as draft
    • publishes
  6. Deletes older translation pages (cleanup)

Why this trigger setup matters (avoid loops and noise)

Trigger

When an item or a file is modified (Site Pages)
Recurrence: every 1 minute

Trigger condition (the important part)

This flow only runs when:

  • the version number contains .0major versions only
  • the page is not a translation page → no recursion

Why:

  • Minor edits / autosaves shouldn’t trigger a translation storm
  • Translation updates would re-trigger the flow endlessly without this check
@and(   contains(triggerBody()?['{VersionNumber}'], '.0'),   not(triggerBody()?['OData__SPIsTranslation']) )

Step 1 — Get the real page content (CanvasContent1)

If you’ve ever tried to translate SharePoint pages with standard SharePoint actions… you’ll hit a wall quickly.

Modern pages store their content in CanvasContent1 — a JSON structure containing sections, controls, and innerHTML blocks.

So instead of relying on standard “Get file content”, this flow uses:

Send an HTTP request to SharePoint (GET)
_api/sitepages/pages({ID})?$select=Language,CanvasContent1

Why:

  • you need CanvasContent1 for real content translation
  • you want to preserve layout, web part structure, and sections

Step 2 — Create translation pages using the SharePoint API

Next, the flow calls:

_api/sitepages/pages({ID})/translations/create

This is SharePoint’s native endpoint to create translation pages.

Why this is better than “copy page” approaches:

  • it creates proper translation pages linked to the original
  • it respects the multilingual framework of SharePoint
  • it gives you culture + path information for each created translation

Step 3 — Loop through each new translation page and resolve the Page ID

The create endpoint returns translation items, but you still need the actual Id of the created Site Page to update it.

So the flow:

  • loops over the created translations
  • calls a GET on sitepages/pages?$filter=Path/DecodedUrl eq '...'
  • extracts the Id
  • stores it in a variable (PageIDNumber)

Why:

  • update/publish endpoints require the page ID

Step 4 — Switch by culture (NL vs FR)

At this point you have:

  • the original page content
  • translation pages created
  • the translation page ID

Now the flow goes into a Switch on culture, for example:

  • nl-nl
  • fr-fr

This is where you can scale later:

  • add German? Add one new case.
  • add author rules per language? Keep it scoped

Case: French (fr-fr)

Translate the Title

For the title the flow uses AI Builder – Text Translation (prebuilt model).

Why AI Builder for title:

  • simple string input/output
  • good integration with structured Power Automate logic

The output becomes the translated page Title.

Translate CanvasContent1 block-by-block (HTML aware)

Then the flow parses CanvasContent1 and loops through each element.

Logic:

  • If innerHTML is not null:
    • translate with Azure Translator (HTML mode)
    • store translated HTML in a variable
    • rebuild the JSON object preserving layout properties (including flexible layout positioning when available)
  • If innerHTML is null:
    • keep the original element untouched

Why do it this way:

  • you only translate the parts that are actual content
  • you don’t break the structure of the page
  • layout data stays intact (sections, positions, control metadata)

This part is “the work”, but it’s also what makes the solution reliable.

Rebuilding the CanvasContent1 by using append to array.

Checkout → Save draft → Publish

For the translated page, the flow runs the classic modern page sequence:

  1. checkout page
  2. SavePageAsDraft with updated CanvasContent1 + Title + metadata (AuthorByline, TopicHeader, BannerImageUrl, …)
  3. publish page

Why this matters:

  • without checkout/draft, you get inconsistent saves
  • without publish, translation pages remain invisible in most real-life setups

Governance and operational notes (don’t skip these)

Permissions

  • HTTP actions require a connection that can call Site Pages endpoints
  • If you run this in production: use a dedicated service account or app registration strategy

Publishing impact

  • Publishing translated pages automatically is powerful
  • But make sure your communication approach matches that:
    • do you want auto-publish or “save as draft and notify” instead?

Trigger frequency

  • The flow checks every minute
  • That’s fine for small/medium environments, but keep an eye on:
    • run counts
    • throttling
    • connector limits

Page complexity

  • CanvasContent1 translation works best when the page is mostly text web parts
  • Highly embedded content (images with text, custom SPFx web parts) won’t “translate” in the same way

What to avoid

  • Translating on every modification (no major version filter) → you’ll create chaos
  • Updating translation pages without excluding translations in the trigger → infinite loops
  • Replacing CanvasContent1 without preserving layout fields → broken page rendering
  • Skipping publish step → users never see the translated pages

Takeaway

If you need multilingual SharePoint pages to stay consistent, you want automation that respects how modern pages actually work.

The winning pattern is:

  • trigger only on major changes
  • read CanvasContent1 via REST
  • translate only innerHTML blocks
  • rebuild JSON safely
  • save draft + publish
  • cleanup old translations

It’s not “a quick flow”, but it’s a reusable blueprint you can apply across intranets and communication sites.

Door Anouck

Een reactie achterlaten

Je e-mailadres zal niet getoond worden. Vereiste velden zijn gemarkeerd met *