Skip to content

v3.0.0

Choose a tag to compare

@58bits 58bits released this 01 Jun 09:08
· 91 commits to main since this release

Highlights

  • @byline/core, @byline/db-postgres, @byline/i18nContent-locale resolution. Document reads now resolve a requested content locale against a per-document fallback chain instead of assuming every value exists in every locale. A new version-grain completeness ledger (byline_document_version_locales) records which locales each version was actually authored in, surfaced on read results as _availableVersionLocales. A new onMissingLocale read switch ('empty' | 'fallback' | 'omit') controls what happens when a requested locale is absent — return empties, fall back to the document's source locale, or omit the field entirely.

  • @byline/core, @byline/db-postgres, @byline/admin, @byline/host-tanstack-startEditorial available-locales advertising. A first-class advertiseLocales: true collection directive replaces the old hand-rolled availableLanguagesField pattern. Editors choose which locales a document advertises via a new admin sidebar widget; the set persists to a document-grain byline_document_available_locales table and is surfaced on reads as availableLocales (with the publicly-safe advertised set being availableLocales ∩ _availableVersionLocales). Wired end-to-end through the admin write path and the client read path.

  • @byline/core, @byline/db-postgres, @byline/adminSwitchable default content locale. Each document now carries its own source_locale anchor, so the site-wide default content locale can be changed safely without rewriting existing data — documents keep reading in the locale they were authored in. Includes a boot-time backfill that stamps source_locale on pre-existing rows, a bulk re-anchor command for moving fully-translated documents onto a new default, and a source-locale badge next to the document title in the editor.

Bug Fixes

  • @byline/i18n, @byline/core — Admin reads now show raw per-locale values rather than fallback-resolved ones, so editors see exactly what exists in each locale. The read-resolution switch was renamed to onMissingLocale as part of this correction.
  • monorepo — Fixed the admin dashboard intermittently rendering "Byline has not been configured" by registering the Byline client config before the admin route loaders run.

Chores

  • @byline/db-postgres — Squashed the migration set to a single 3.0 baseline for fresh installs (supersedes 00000004), with a standalone, idempotent sql/upgrade-2.7.0-to-3.0.sql delta script for existing installs.
  • @byline/cli — Brought templates and the init migration to 3.0, and migrated import-docs from availableLanguages to advertiseLocales.

Migrations

  • @byline/db-postgresExisting installs: apply the schema delta with psql "$DATABASE_URL" -f packages/db-postgres/sql/upgrade-2.7.0-to-3.0.sql (equivalent to migrations 00010004; transactional and re-runnable). Do not run drizzle:migrate against an upgraded DB — after the squash its journal points at superseded hashes. Fresh installs run the squashed baseline via drizzle:migrate.
  • monorepoRequired data backfill: run cd apps/webapp && pnpm tsx byline/scripts/backfill-version-locales.ts to populate the version-locale ledger for pre-existing documents (without it, onMissingLocale: 'omit' reads can't see old docs and _availableVersionLocales is empty on old versions). The source_locale backfill is automaticinitBylineCore() stamps NULL rows on boot, so deploying the 3.0 server is the backfill. Full per-site guide in docs/MIGRATION-TO-3.0.md.

Breaking Changes

  • @byline/client, @byline/corebreaking: the ClientDocument read surface renamed _availableLocales_availableVersionLocales (the structural ledger fact), and added the editorial availableLocales and _localeAgnostic. Any frontend reading _availableLocales (e.g. hreflang / "also available in…" UI) must move to the new fields.
  • @byline/corebreaking: availableLocales is now a reserved field name — a collection can no longer declare a user field by that name. The deprecated availableLanguagesField() pattern is retired; collections using it must remove the field and its import and add advertiseLocales: true to the collection definition.
  • @byline/corebreaking (semantics): i18n.content.defaultLocale is no longer the data anchor — it now means "default authoring locale + request fallback," with each document riding its own source_locale. No code change required, but switching it now affects new authoring/fallback behaviour rather than rewriting existing data.

All other @byline/* packages bumped to 3.0.0 in lockstep with no behavioural changes this cycle.