---
title: "Translations — Posts for Laravel | Roundly"
description: "Per-locale titles, perexes, bodies and SEO meta stored as JSON — write, read and the exact fallback order."
url: https://roundly-consulting.com/open-source/docs/posts-for-laravel/translations
language: en
---

[All packages](https://roundly-consulting.com/open-source.md)

[Posts for Laravel](https://roundly-consulting.com/open-source/docs/posts-for-laravel.md)

# Translations

Translatable attributes are JSON columns holding a locale => value map, resolved by the package’s own HasTranslatableAttributes concern — no third-party translation library. On a post they are title, slug, perex, content, meta\_title and meta\_description; on categories and tags, name and slug.

## Writing translations

```php
use RoundlyConsulting\Posts\Facades\Posts;

$post = Posts::draft()
    ->title('en', 'Hello world')
    ->title('sk', 'Ahoj svet')
    ->content('en', '<p>…</p>')
    ->by($user)                      // polymorphic author
    ->save();

// Plain Eloquent works too — edit translations on the model and save:
$post->setTranslation('perex', 'en', 'A short intro');
$post->save();
```

The builder saves through Posts::create(); setTranslation() returns the model and does not save — call save() yourself. Slugs are generated per locale from the title on save (see Slugs).

## Reading translations

```php
$post->getTranslation('title', 'sk');          // 'Ahoj svet' (with fallback)
$post->getTranslation('title', 'de', false);   // '' — exact locale, no fallback
$post->getTranslations('title');               // ['en' => 'Hello world', 'sk' => 'Ahoj svet']

$post->translate('title');                     // current-locale value, with fallback
$post->translate('title', 'sk');               // a given locale, with fallback
$post->title;                                  // same as translate('title')

$post->isTranslatableAttribute('title');       // true
$post->translatableAttributes();               // ['title', 'slug', 'perex', 'content', 'meta_title', 'meta_description']
```

## Fallback order

A read with fallback tries, in order:

- the requested locale;
- the fallback locale — the first one set of translatable.fallback\_locale (when translatable-for-laravel is configured), posts.locales.fallback and app.fallback\_locale; a blank one is not set and passes to the next;
- the lowest-sorting locale that holds a value — a stable choice, independent of the key order the database returns JSON in.

Direct attribute access ($post->title) resolves through this chain unless the model defines an accessor or mutator for the key. Pass false as the third argument of getTranslation() to read one exact locale; it returns '' when that locale is missing.

## Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

[More ways to support, including crypto](https://roundly-consulting.com/support-us.md)

By donating, you agree to our [donation terms](https://roundly-consulting.com/donation-terms.md).

[Support our open source work (opens in a new tab)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Join us on Patreon (opens in a new tab)](https://www.patreon.com/cw/roundly)

## Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.

[Get a quote in 48 hours](https://roundly-consulting.com/contact.md) [Browse all packages](https://roundly-consulting.com/open-source/docs/posts-for-laravel.md)
