Skip to content

feat(agentic-localization): upgrade document-internationalization v5 → v6#20

Merged
nkgentile merged 4 commits intomainfrom
upgrade/document-internationalization-v6
Mar 14, 2026
Merged

feat(agentic-localization): upgrade document-internationalization v5 → v6#20
nkgentile merged 4 commits intomainfrom
upgrade/document-internationalization-v6

Conversation

@nkgentile
Copy link
Contributor

@nkgentile nkgentile commented Mar 12, 2026

Summary

Upgrades @sanity/document-internationalization v5 → v6 and sanity-plugin-internationalized-array v4 → v5.

Breaking change in the plugins: Array items in translations[] and workflowStates[] now use a dedicated language field for the locale identifier instead of _key. Previously _key held the locale code (e.g., "en-US"); now _key is a random unique ID and language carries the locale code.

Changes

  • Version bumps: @sanity/document-internationalization ^5.1.0^6.0.0, sanity-plugin-internationalized-array ^4.0.3^5.0.0
  • GROQ queries: translations[_key == ...]translations[language == ...], added language to projections
  • Patch operations: translations[_key=="..."] / workflowStates[_key=="..."][language=="..."]
  • Code reads: t._key / entry._key.language everywhere locale was read from _key
  • Entry creation: _key: localeId_key: randomKey(12), language: localeId (or omit _key with autoGenerateArrayKeys: true)
  • Auto-generate keys: All .commit() calls on client transactions/patches use {autoGenerateArrayKeys: true} so _key is auto-generated by the Content Lake
  • Studio patch.execute(): Uses randomKey(12) from @sanity/util/content manually (Studio document store doesn't support autoGenerateArrayKeys)
  • Reference strength: Both createReference functions include _strengthenOnPublish: {type} so weak refs auto-strengthen when the referenced doc is published
  • Shared types:
    • LocalizedObject type (KeyedObject & {language: string}) using LANGUAGE_FIELD_NAME const from the plugin
    • WorkflowStateEntry extends LocalizedObject
    • TranslationMetadataEntry extends LocalizedObject
    • createReference return typed as Omit<TranslationReference, '_key'> using the plugin's type
    • All inline {_key: string; language: string; ...} patterns replaced with LocalizedObject & {...}
  • Schema: Added language field to workflowStates array member in metadataFields.ts

Files changed

Packages:

  • packages/l10n/src/core/types.tsLocalizedObject type, WorkflowStateEntry updated
  • packages/l10n/src/index.ts — export LocalizedObject
  • packages/l10n/src/translations/useTranslateActions.tscreateReference, approve/dismiss, all GROQ
  • packages/l10n/src/translations/useTranslationPaneData.ts — GROQ queries
  • packages/l10n/src/translations/createTranslationPanePlugin.ts — GROQ filter
  • packages/l10n/src/schemas/metadataFields.ts — schema field
  • packages/l10n/src/core/staleAnalysisCache.tsautoGenerateArrayKeys
  • packages/l10n/package.json@sanity/util dependency

Dashboard app:

  • apps/translations-dashboard/src/lib/createReference.tsTranslationReference type, _strengthenOnPublish
  • apps/translations-dashboard/src/lib/metadataOperations.tsLocalizedObject, autoGenerateArrayKeys
  • apps/translations-dashboard/src/lib/processDocumentTranslations.tsautoGenerateArrayKeys, .language
  • apps/translations-dashboard/src/contexts/TranslationStatusContext.tsxLocalizedObject inline types
  • apps/translations-dashboard/src/hooks/useTranslationAggregateData.tsLocalizedObject
  • apps/translations-dashboard/src/hooks/useCreateMissingTranslations.tsautoGenerateArrayKeys
  • apps/translations-dashboard/src/hooks/useRetranslateStale.tsautoGenerateArrayKeys
  • apps/translations-dashboard/src/hooks/useGapDocuments.ts, useStatusBreakdown.ts, useStatusFilteredDocuments.ts, useCoverageMatrix.ts, useTranslationSummary.ts, useRecentChanges.ts.language
  • apps/translations-dashboard/src/queries/metadataQueries.ts — GROQ projections
  • apps/translations-dashboard/src/helpers/translationStatus.ts — GROQ projections
  • apps/translations-dashboard/src/components/DocumentDetail/TranslationsList.tsx.language

Functions:

  • functions/mark-translations-stale/index.ts.language reads and patches
  • functions/analyze-stale-translations/index.ts.language reads, legacy normalize

Studio:

  • studio/scripts/seed/briefs.ts — seed data entries use language field

Test plan

  • Install deps: pnpm install
  • Typecheck: pnpm --filter l10n typecheck && pnpm --filter translations-dashboard typecheck && pnpm --filter studio typecheck
  • Import sample data: pnpm --filter studio run import-sample-data
  • Open Studio, verify articles show in Translations pane
  • Translate a document — verify translation.metadata has language field on entries
  • Verify workflowStates entries have language field with random _key
  • Approve a translation — verify workflow state updates correctly
  • Edit + publish base doc — verify stale detection marks translations as stale
  • Open translations dashboard — verify document list, status badges, coverage matrix
  • Verify no "Reference strength mismatch" warnings on metadata docs

…tion v5 → v6

Breaking change in the plugin: array items in `translations[]` and
`workflowStates[]` now use a dedicated `language` field for the locale
identifier instead of `_key`. `_key` is now a random unique ID
auto-generated by the backend.

- Bump `@sanity/document-internationalization` ^5.1.0 → ^6.0.0
- Bump `sanity-plugin-internationalized-array` ^4.0.3 → ^5.0.0
- Add `language` field to workflowStates schema definition
- Update all GROQ queries: `translations[_key == ...]` → `translations[language == ...]`
- Update all GROQ patch operations: `[_key=="..."]` → `[language=="..."]`
- Update all code reading `_key` as locale to use `language` instead
- Remove `_key` from mutation payloads (auto-generated by backend)
- Remove local `randomKey` utility — no longer needed
- Remove legacy v5 backward-compat code (object-shape handling, `?? _key` fallbacks)
- Delete `apps/translations-dashboard/src/types.ts` (use plugin's `TranslationReference`)
- Regenerate TypeGen types
@nkgentile nkgentile temporarily deployed to ai-shopping-assistant March 12, 2026 02:55 — with GitHub Actions Inactive
@nkgentile nkgentile temporarily deployed to agentic-localization March 12, 2026 02:55 — with GitHub Actions Inactive
@nkgentile nkgentile temporarily deployed to agentic-localization March 12, 2026 02:55 — with GitHub Actions Inactive
@vercel
Copy link

vercel bot commented Mar 12, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ai-shopping-assistant Ready Ready Preview, Comment Mar 13, 2026 7:17pm

Request Review

…refs on publish

Patch operations (append/insert) don't auto-generate _key like
document creation does. Use `autoGenerateArrayKeys: true` on all
`.commit()` calls. For Studio `patch.execute()` (which doesn't
support the flag), use `randomKey()` from `@sanity/util/content`.

Also add `_strengthenOnPublish` to translation reference creation
so the Content Lake auto-strengthens weak refs once the referenced
document is published (translation.metadata is liveEdit).
…types for refs

- Add LocalizedObject (KeyedObject + LANGUAGE_FIELD_NAME) as shared base type
- Use LocalizedObject for WorkflowStateEntry, TranslationMetadataEntry,
  MetadataDoc, and inline fetch types in TranslationStatusContext
- Annotate createReference return types with Omit<TranslationReference, '_key'>
- Remove all inline {_key: string; language: string} patterns
Copy link
Contributor

@kenjonespizza kenjonespizza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nkgentile 👏 . I've not had a chance to test this, but I love the upgrade. If you've tested and feel good, Im happy for you to merge. Otherwise I can test later today

@kenjonespizza kenjonespizza self-requested a review March 13, 2026 16:03
kenjonespizza

This comment was marked as outdated.

@kenjonespizza
Copy link
Contributor

Other than the suggested change, I successfully ran through and tested all testing steps! Great work Noah!

…ta list

translation.metadata has no stored `title` field (it's computed via
preview.prepare), so defaultOrdering by title causes a Studio error.
@kenjonespizza kenjonespizza temporarily deployed to ai-shopping-assistant March 13, 2026 19:15 — with GitHub Actions Inactive
@kenjonespizza kenjonespizza temporarily deployed to agentic-localization March 13, 2026 19:15 — with GitHub Actions Inactive
@kenjonespizza kenjonespizza temporarily deployed to agentic-localization March 13, 2026 19:15 — with GitHub Actions Inactive
@kenjonespizza kenjonespizza self-requested a review March 13, 2026 19:16
Copy link
Contributor

@kenjonespizza kenjonespizza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I committed the fix to the only bug I found. Nice work Noah!

kenjonespizza added a commit that referenced this pull request Mar 13, 2026
…i18n, editorial workflow, and slug uniqueness

Reflects recent PRs (#15, #18, #20, #21): adds field-level localization
section, slug uniqueness per language, editorial review workflow
(review → approved → stale + publish gating), and Sanity Functions to
the system diagram.
@nkgentile nkgentile merged commit 5f91337 into main Mar 14, 2026
5 checks passed
@nkgentile nkgentile deleted the upgrade/document-internationalization-v6 branch March 14, 2026 05:05
kenjonespizza added a commit that referenced this pull request Mar 17, 2026
…i18n, editorial workflow, and slug uniqueness (#22)

Reflects recent PRs (#15, #18, #20, #21): adds field-level localization
section, slug uniqueness per language, editorial review workflow
(review → approved → stale + publish gating), and Sanity Functions to
the system diagram.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants