---
title: "Payload localizeStatus: Per-Locale Draft Publishing Guide"
slug: "payload-localizestatus-per-locale-draft-publishing"
published: "2026-03-16"
updated: "2026-03-02"
validated: "2026-03-02"
categories:
  - "Payload"
tags:
  - "Payload localizeStatus"
  - "per-locale publishing"
  - "localized status Payload"
  - "Payload v3.72"
  - "multilingual content workflow"
  - "draft publishing per locale"
  - "Payload _status per locale"
  - "next-intl routing"
  - "PostgreSQL join fields bug"
  - "localized fields"
llm-intent: "reference"
audience-level: "intermediate"
framework-versions:
  - "payload@3.72+"
  - "next.js@15"
  - "typescript@5.x"
  - "next-intl@latest"
status: "stable"
llm-purpose: "Payload localizeStatus lets you publish per-locale drafts independently. Learn setup, query patterns and known bugs before production — read the guide now."
llm-prereqs:
  - "Access to Payload CMS"
  - "Access to TypeScript"
  - "Access to Next.js"
  - "Access to next-intl"
  - "Access to next/headers (draftMode)"
llm-outputs:
  - "Completed outcome: Payload localizeStatus lets you publish per-locale drafts independently. Learn setup, query patterns and known bugs before production — read the guide now."
---

**Summary Triples**
- (Payload localizeStatus: Per-Locale Draft Publishing Guide, focuses-on, Payload localizeStatus lets you publish per-locale drafts independently. Learn setup, query patterns and known bugs before production — read the guide now.)
- (Payload localizeStatus: Per-Locale Draft Publishing Guide, category, general)

### {GOAL}
Payload localizeStatus lets you publish per-locale drafts independently. Learn setup, query patterns and known bugs before production — read the guide now.

### {PREREQS}
- Access to Payload CMS
- Access to TypeScript
- Access to Next.js
- Access to next-intl
- Access to next/headers (draftMode)

### {STEPS}
1. Understand the feature change
2. Enable experimental flag
3. Enable per-collection localizeStatus
4. Query published content per locale
5. Implement draft previews
6. Assess known bugs and readiness

<!-- llm:goal="Payload localizeStatus lets you publish per-locale drafts independently. Learn setup, query patterns and known bugs before production — read the guide now." -->
<!-- llm:prereq="Access to Payload CMS" -->
<!-- llm:prereq="Access to TypeScript" -->
<!-- llm:prereq="Access to Next.js" -->
<!-- llm:prereq="Access to next-intl" -->
<!-- llm:prereq="Access to next/headers (draftMode)" -->
<!-- llm:output="Completed outcome: Payload localizeStatus lets you publish per-locale drafts independently. Learn setup, query patterns and known bugs before production — read the guide now." -->

# Payload localizeStatus: Per-Locale Draft Publishing Guide
> Payload localizeStatus lets you publish per-locale drafts independently. Learn setup, query patterns and known bugs before production — read the guide now.
Matija Žiberna · 2026-03-16

One of the most common requests I get from agency clients running multilingual sites is simple to explain but surprisingly hard to implement: "Can we launch the English site now and keep the German version in draft until we finish the translations?"

Before Payload v3.72.0, the answer involved workarounds — separate collections, custom status fields, or shipping incomplete content behind feature flags. As of January 2026, Payload has a native solution: `localizeStatus`. It lets you manage publication status independently per locale, so publishing English doesn't force German live, and unpublishing one language doesn't take down the others.

It's currently marked as experimental and beta, which means it works but you should test thoroughly before relying on it in production. This guide covers the setup, how it changes your data shape, how to query correctly with it enabled, and the known bugs worth knowing about before you ship.

## What Changes With `localizeStatus` Enabled

Without `localizeStatus`, a document's `_status` field is a single string representing one status across all locales:

```typescript
// Default behavior — one status for all locales
{
  id: '123',
  title: 'Our Services',
  _status: 'published',
}
```

With `localizeStatus` enabled, `_status` becomes an object keyed by locale — each language tracks its own publication state independently:

```typescript
// With localizeStatus — status per locale
{
  id: '123',
  title: {
    en: 'Our Services',
    de: 'Unsere Leistungen',
    sl: 'Naše storitve',
  },
  _status: {
    en: 'published',
    de: 'draft',
    sl: 'published',
  },
}
```

In the admin UI, the status indicator changes based on which locale the editor is currently viewing. Editors can publish, unpublish, or save as draft for just the locale they're working in without touching the others.

## Setup: Two Places, Both Required

Enabling `localizeStatus` requires changes in two places. Missing either one means it won't work.

First, enable the experimental flag at the top-level Payload config:

```typescript
// File: payload.config.ts
import { buildConfig } from 'payload'

export default buildConfig({
  experimental: {
    localizeStatus: true,
  },
  localization: {
    locales: [
      { label: 'English', code: 'en' },
      { label: 'Deutsch', code: 'de' },
      { label: 'Slovenščina', code: 'sl' },
    ],
    defaultLocale: 'en',
    fallback: true,
  },
  // ... rest of config
})
```

Second, enable it per collection (or global) that needs per-locale status management:

```typescript
// File: src/collections/Pages/index.ts
import type { CollectionConfig } from 'payload'

export const Pages: CollectionConfig = {
  slug: 'pages',
  versions: {
    drafts: {
      localizeStatus: true,
    },
  },
  fields: [
    {
      name: 'title',
      type: 'text',
      localized: true,
    },
    {
      name: 'content',
      type: 'richText',
      localized: true,
    },
    {
      name: 'slug',
      type: 'text',
      localized: true,
    },
  ],
}
```

Not every collection needs `localizeStatus`. Enable it only on collections where independent per-locale publishing is actually required. A settings collection shared across all languages probably doesn't need it. A pages collection where each market manages its own content does.

## Querying Published Content Per Locale

With `localizeStatus` enabled, the standard pattern for fetching published content combines `locale` with a `_status` filter. The Payload REST API docs show this pattern explicitly:

```typescript
// File: src/lib/payload/getPages.ts
import { getPayload } from 'payload'
import config from '@payload-config'
import type { Locale } from '@/i18n/routing'

export async function getPublishedPages(locale: Locale) {
  const payload = await getPayload({ config })

  const result = await payload.find({
    collection: 'pages',
    locale,
    fallbackLocale: 'en',
    where: {
      _status: { equals: 'published' },
    },
  })

  return result.docs
}
```

Pass the locale from next-intl's routing and filter on `_status: 'published'` — Payload resolves the status check against the locale-specific status value. A German editor who has saved a page as draft won't surface it in the German frontend, while the English version of the same document remains live.

For draft preview mode, where you want editors to see unpublished content:

```typescript
// File: src/lib/payload/getPageBySlug.ts
import { getPayload } from 'payload'
import config from '@payload-config'
import { draftMode } from 'next/headers'
import type { Locale } from '@/i18n/routing'

export async function getPageBySlug(slug: string, locale: Locale) {
  const { isEnabled: isDraft } = await draftMode()
  const payload = await getPayload({ config })

  const result = await payload.find({
    collection: 'pages',
    locale,
    fallbackLocale: 'en',
    draft: isDraft,
    limit: 1,
    where: {
      slug: { equals: slug },
      ...(!isDraft && { _status: { equals: 'published' } }),
    },
  })

  return result.docs[0] ?? null
}
```

When draft mode is active, the `_status` filter is omitted so editors can preview unpublished content. In normal rendering, only published content surfaces.

## The Agency Workflow This Enables

The practical flow for a client launching English first and German second looks like this in Payload's admin:

The content team creates pages in English, fills in all the English fields, and publishes them locale by locale — each publish action affects only the currently selected locale. German fields exist in the document but remain in draft. The English frontend goes live. German editors then work through translations at their own pace, publishing German locale by locale as translations complete, without any risk of accidentally taking down English content or publishing incomplete German pages.

The admin UI handles this by always showing the status of the currently selected locale. An editor working in German who opens a page sees "Draft" even if the English version is published. When they're ready, they publish just the German locale.

## Known Bugs Before You Ship

`localizeStatus` was introduced as experimental in v3.72.0 and there are active bugs worth knowing about before committing it to a production project.

**SQL error with join fields (issue #15248)**

If your collection has a join field and you query with `draft: true` and a `locale` parameter, Payload generates an invalid SQL query on PostgreSQL:

```
invalid reference to FROM-clause entry for table '_r_v'
```

If you hit this, the reported workarounds are removing `localizeStatus: true` temporarily, or checking whether a `defaultSort` on a related collection is involved. This is an active open issue.

**Unnamed group fields lose data on localized publish (issue #15642)**

If your collection has a `group` field without a `name` property, any fields inside that group lose their data when you publish a single locale. This affects both localized and non-localized fields inside the unnamed group. A fix was committed (38b8c68) in a subsequent release — check that you're on a version after v3.76.1 where this was reported.

**Unpublish dropdown visible without `localizeStatus` (issue #15291)**

A minor UI issue: the "Unpublish in [locale]" dropdown button appears even when `localizeStatus` is not enabled on the collection. The Payload team acknowledged it and noted a design solution is coming. It's cosmetic and doesn't affect data, but worth flagging to clients who might be confused by it.

## Is It Ready for Production?

The honest answer is: carefully. The Payload docs themselves say to test thoroughly before using in production, and the active bugs above are real. If your project is on PostgreSQL with join fields, hold off until issue #15248 is resolved. If you're on MongoDB or your collections don't use join fields, the feature works well for its core purpose.

For new projects starting now, it's worth building with `localizeStatus` in mind even if you don't enable it immediately — making your fields `localized: true` from the start means you can turn on `localizeStatus` later without a migration.

The underlying workflow it enables — independent publication status per locale — is genuinely useful for agency work and something clients ask for. Worth keeping an eye on as it moves from experimental toward stable.

Let me know in the comments if you've hit other edge cases with `localizeStatus` in your projects. Subscribe for more practical development guides.

Thanks, Matija

## LLM Response Snippet
```json
{
  "goal": "Payload localizeStatus lets you publish per-locale drafts independently. Learn setup, query patterns and known bugs before production — read the guide now.",
  "responses": [
    {
      "question": "What does the article \"Payload localizeStatus: Per-Locale Draft Publishing Guide\" cover?",
      "answer": "Payload localizeStatus lets you publish per-locale drafts independently. Learn setup, query patterns and known bugs before production — read the guide now."
    }
  ]
}
```