# Content localization: push notifications for new posts are sent before the translation is stored

**URL:** <https://meta.discourse.org/t/content-localization-push-notifications-for-new-posts-are-sent-before-the-translation-is-stored/413952>\
**Category:** Feature\
**Tags:** push-notifications, ai, content-localization\
**Created:** [October 5, 2026, 11:49am UTC](https://meta.discourse.org/t/content-localization-push-notifications-for-new-posts-are-sent-before-the-translation-is-stored/413952 "2026-10-05T11:49:29Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sailor](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/sailor/32/579029_2.png) [@Sailor](https://meta.discourse.org/u/Sailor)\
**Post date:** [October 5, 2026, 11:49am UTC](https://meta.discourse.org/t/content-localization-push-notifications-for-new-posts-are-sent-before-the-translation-is-stored/413952/1 "2026-10-05T11:49:29Z")

</div>

## Summary

With content localization and AI translation enabled, the push notification for a new post almost always carries the author’s original text, even when the recipient reads another language and a translation is stored a few seconds later. The push is queued when the post is created and looks for a translation once, before the translation job has finished.

Translated emails were announced today in [this reply](https://meta.discourse.org/t/use-translated-posts-when-emailing-users-with-their-user-language-set/383546/16) ([#44240](https://github.com/discourse/discourse/pull/44240)). Emails are not exposed to this timing and push is, so once that change is deployed the email and the push for the same post will reach the same member in different languages.

## What a member sees

A member whose interface language is English receives a push notification, in the browser and on mobile, for a new topic written in French. The notification body is in French. Opening the notification shows the post in English.

## Measurement

Site on `release/2026.7` (2026.7.3) with the bundled discourse-ai plugin, supported locales `en`, `fr`, `de` and `it`, translation on `gemini-3.8-flash` and language detection on `gemini-3.5-flash-lite`.

For 11 translated posts the first translation was stored 2 to 3 seconds after the post was created, and the last of the three 4 to 7 seconds after. In the observed case the translation into the recipient’s language was stored 2 seconds after the post, and the push had already gone out with the original text.

The delay can be read on any site with:

```sql
SELECT p.id,
       p.locale AS post_locale,
       pl.locale AS translation_locale,
       ROUND(EXTRACT(EPOCH FROM (pl.created_at - p.created_at))) AS seconds_after_post
FROM posts p
JOIN post_localizations pl ON pl.post_id = p.id
WHERE p.created_at > NOW() - INTERVAL '2 days'
ORDER BY p.id, pl.created_at

```

## Cause

1. On `:post_created`, discourse-ai enqueues `Jobs::DetectTranslatePost` (`plugins/discourse-ai/lib/translation/entry_point.rb`). The job detects the language with one model call and then translates into each other supported locale in turn.
2. `PostJobsEnqueuer` enqueues `:post_alert` at the same moment. `PostAlerter.push_notification` enqueues `Jobs::DeliverPushNotification` immediately. It is delayed only when the recipient was seen within `push_notification_time_window_mins` (default 1), and then only by the remainder of that window.
3. `DeliverPushNotification#localize_content!` looks up `TopicLocalization` and `PostLocalization` for `user.effective_locale` once, when the job runs. Finding none, it sends the original title and excerpt. Nothing waits or retries.
4. Notification emails go through `NotificationEmailer` with a delay of `email_time_window_mins` (default 10), so the translation exists by the time the email is built.

`app/jobs/regular/deliver_push_notification.rb` is identical at `v2026.7.3` and on `main` at `b5548f76` (2026-10-05).

## Request

1. **Hold the push for a new post until its translation is stored.** One option: when content localization is enabled and the post has no detected locale yet, or no localization for the recipient’s locale while one is expected, re-enqueue `DeliverPushNotification` once after a short delay and then send whatever is available. A few seconds would cover the cases measured above.
2. **Select the content with the shared rule.** The push job does its own lookup by `effective_locale`. The email change in #44240 goes through `ContentLocalization.show_translated_post?` and compares `post_version`. Using the same path for push would make it respect `automatically_translate` and `understood_languages`, skip stale translations, and stay consistent with emails and the topic view.
3. **Apply the same to live alerts.** The payload published to `/notification-alert/:user_id` in `PostAlerter.create_notification_alert` carries the original title and excerpt. The modifier `post_alerter_live_notification_payload` exists, but core does not localize the payload.

## Related

- [Use translated posts when emailing users with their user language set](https://meta.discourse.org/t/use-translated-posts-when-emailing-users-with-their-user-language-set/383546)
- [FEATURE: Use translated content in notification and digest emails (#44240)](https://github.com/discourse/discourse/pull/44240)
