Collaborate, Innovate, Automate

Building a Translation Governance Dashboard for Multilingual SharePoint

23 June 2026 SharePoint Governance PNP PowerShell SPFX

SharePoint Online's multilingual pages feature handles the mechanics of translation reasonably well. Create a page, add languages, notify your translators, and the framework takes care of linking source pages to their translated counterparts. What it does not handle is the question that comes six months later: are those translations still accurate?

Content changes. Policies get updated. Procedures are revised. A page that was perfectly translated in October may be significantly out of date by March, and unless someone is manually checking the Translation pane on every page — one at a time — there is no way to know. This is translation drift, and it is one of the most common and least visible governance failures in multilingual intranet deployments.

This post covers a translation governance toolkit built to solve that problem: two PnP PowerShell scripts and an SPFx web part that together give you a site-wide view of translation health, updated on demand or on a schedule.

What Translation Drift Actually Costs

The immediate cost is obvious — users reading the French version of a page see content that no longer reflects current policy or process. For an intranet that exists to communicate accurate information across a multilingual workforce, that is a fundamental failure of purpose.

The less obvious cost is trust. Once users learn that the French content cannot be relied upon to match the English, they stop using it — and the investment in the multilingual infrastructure becomes difficult to justify. Rebuilding that trust requires not just fixing the stale pages but demonstrating that there is a governance process in place to prevent it happening again.

A translation drift dashboard is both the diagnostic tool and the proof of process. It shows what is stale, who is responsible for fixing it, and — when run regularly — provides the audit trail that demonstrates the translation process is being actively managed.

How SharePoint Links Source Pages to Translations

Before building anything, it helps to understand how SharePoint's multilingual pages feature actually connects source pages to their translations under the hood.

When a translated page is created, SharePoint sets a field called _SPTranslationSourceItemId on the translation page. This field contains the UniqueId of the source page — the internal SharePoint identifier that is distinct from the GUID field returned by standard list queries. The translated page also carries _SPIsTranslation (a boolean confirming it is a translation) and _SPTranslationLanguage (the locale code, for example fr-fr).

This is the link the drift script exploits. By loading all pages from the Site Pages library, separating source pages from translations, and matching them via _SPTranslationSourceItemId against source page UniqueId values, we can reliably pair every English page with its French counterpart — or flag it as missing one.

One important nuance discovered during development: _SPTranslationSourceItemId points to the page's UniqueId, not the GUID field that Get-PnPListItem returns by default. These are different values. The script explicitly requests UniqueId as a field and uses it as the matching key.

The Toolkit

The solution is three pieces that work together:

  • Create-TranslationDriftList.ps1 — a one-time setup script that provisions a TranslationDrift SharePoint list with 15 columns covering page identification, drift calculation, translator ownership, and nudge tracking. Idempotent — safe to re-run.
  • Get-TranslationDrift.ps1 — the drift detection script. Scans Site Pages, matches source pages to translations, calculates drift in days, and populates the TranslationDrift list with a status of In Sync, Stale, or Missing per page. Can be run manually or scheduled via an Azure Automation Runbook.
  • Translation Drift Dashboard SPFx web part — reads the TranslationDrift list and renders an interactive dashboard with summary tiles, a sortable and filterable table, colour-coded status pills, and direct links to both the source and translated pages.
Translation Drift Dashboard web part showing summary tiles and a sortable table of page translation status

Drift Status Logic

Each page gets one of three statuses:

In Sync — a French translation exists and was modified within the configured stale threshold (default 7 days) of the English source page's last modification. The translation is considered current. Note that a French page modified after its English source also shows as In Sync — this is correct behaviour under the assumption that changes always flow English → French. If someone updates the French page independently without first updating the English source, the dashboard will not flag it. That edge case is a genuine governance nuance: the toolkit assumes English is always the source of truth, and any independent edits to translated pages that don't correspond to an English update sit outside what drift detection alone can catch. A content governance policy that makes this expectation explicit — and a periodic manual review of the French modified dates — is the complementary control.

Stale — a French translation exists but the English source has been modified more than the threshold number of days more recently than the translation. The translation may no longer reflect current content.

Missing — no French translation page exists for this source page at all. It has either never been translated or the translation was deleted.

The stale threshold is configurable in both the script ($StaleDays variable) and the web part property pane, so organisations with different translation SLAs can adjust accordingly.

What the Dashboard Surfaces

The summary tiles at the top give an immediate health snapshot. Clicking any tile filters the table to that status group — so a site owner can click Stale and immediately see only the pages that need attention, sorted by days drift descending to prioritise the most overdue first.

The table columns tell the full governance story for each page:

  • Page — the English source page title, linked directly to the page
  • Status — colour-coded pill: green (In Sync), amber (Stale), red (Missing)
  • Days drift — how many days out of sync the translation is; shown in red when over 30 days
  • EN modified — when the English source was last updated
  • FR modified — when the French translation was last updated
  • Translator — the site owner, who is the responsible party for translation governance on this site
  • FR page — a direct View link to the French translation for quick access

Building It: The Interesting Technical Problems

Two things that weren't obvious going in and are worth documenting for anyone building something similar.

The UniqueId vs GUID Problem

As mentioned above, _SPTranslationSourceItemId does not match the GUID field from Get-PnPListItem. Spending time trying to match on GUID and getting zero results every time is a good indicator that this is your problem. The fix is to explicitly request UniqueId as a field:

Get-PnPListItem -List "Site Pages" -Fields "Title","FileRef","UniqueId","_SPTranslationSourceItemId"

Then build your lookup hashtable keyed on UniqueId.ToString().ToLower() and match against _SPTranslationSourceItemId.ToString().ToLower().

Folder Items in Site Pages

The Site Pages library uses folders for section navigation — items like Policies, Guidelines, Process Manuals that appear as folders in the library but show up as list items in Get-PnPListItem. These need to be excluded from the drift calculation since they are navigation containers, not translatable content pages. The fix is to filter on the .aspx extension:

$_.FieldValues["FileRef"] -match "\.aspx$"

Simple but not immediately obvious when you see folders appearing in your results with Missing status.

Running It

First time setup:

# 1. Provision the list
.\Create-TranslationDriftList.ps1

# 2. Run the drift scan
.\Get-TranslationDrift.ps1

Subsequent runs — just run Get-TranslationDrift.ps1. It detects existing list items via a hashtable lookup and updates them rather than creating duplicates.

For ongoing governance — run the drift script monthly (or weekly for high-activity sites) via Azure Automation with certificate-based authentication. The web part always reflects the most recent run, so the dashboard stays current without manual intervention.

What Comes Next

The toolkit as built covers detection and visibility. The natural next steps are:

Nudge notifications — a Power Automate flow triggered by the drift script run that emails the translator with a list of their stale and missing pages. The TranslatorEmail and NudgeSent columns in the TranslationDrift list are already designed for this.

Multi-site scanning — extending the drift script to accept a list of site URLs and populate a single cross-site dashboard, giving intranet managers visibility across an entire tenant rather than site by site.

Multi-language support — the script currently targets fr-fr specifically. Extending it to loop across all configured translation languages would make it useful for organisations with three or more intranet languages.


Cameron Griffiths is a Microsoft 365 consultant based in Valencia, Spain, specialising in SharePoint Online, Power Automate and Microsoft 365 for business. camerongriffiths.com