Amazon S3

A bucket in, a bucket out, or both

Two one-way integrations you compose. S3 Export publishes every language in your project to a bucket in one push, formatted by your project settings and ready to sit behind a CDN. S3 Import pulls translation files from a bucket back into the project, whether that is a tidy locale folder or files another pipeline drops wherever it pleases.

A push is a full publish: the same objects, overwritten in place, safe to run twice. Nothing is ever deleted from your bucket.

s3.console.aws.amazon.com/s3/buckets/acme-web-locales

acme-web-locales eu-central-1

acme-web-locales / locale/

NameSizeLast modified
en.json 4.2 KB a minute ago
de.json 4.6 KB a minute ago
fr.json 4.5 KB a minute ago
tr.json 4.3 KB a minute ago

One object per language, overwritten in place on every push.

Illustration of the bucket a push leaves behind, drawn rather than screenshotted so the object list stays readable text.

How it works

Files in a bucket, not files in an inbox

Export names each file by your structure pattern, {LANG_ISO}.{FORMAT} for one object per language or a per-language folder layout, under the prefix you chose. Formatting comes from the project’s settings (indentation, key order, nesting, plural style), so two pushes of the same translations produce byte-identical objects: CDNs cache them cleanly and diff tools stay quiet.

Import reads the bucket the same way, or switches to a glob pattern like **/*.json when the files were scattered by a build pipeline rather than arranged for translation. It adds new keys and fills empty values, and touches nothing else unless you switch on update existing.

s3-export

The publish

Every language, one push, objects overwritten in place. Idempotent by design: rerunning it cannot make a mess, only make the bucket current.

s3-import

The intake

Structure mode for locale folders, glob mode for everything else. Every run reports what it added, updated and skipped, and a limit check runs before anything is written.

two rows

Deliberately split

Import and export are separate integrations: different buckets, different credentials, different lifecycles. Run one, the other, or both at once.

Setup

A bucket, one IAM user, and a test button

About five minutes per direction. You will need a project role in locamorph that can manage integrations, and enough AWS access to create an IAM user and attach a policy.

  1. Choose S3 Import or S3 Export on the Integrations page

    Each direction is its own card and its own configuration. This is also where the integration lives later: status, settings and revoke all stay on this one screen.

  2. Create an IAM user scoped to the bucket

    In AWS, create an IAM user for exactly this purpose, attach a least-privilege policy like the one below, and mint an access key for it. No root keys, no account-wide access: list, read and write on one named bucket and nothing else.

    iam-policy.json
    {
      "Version": "2012-10-17",
      "Statement": [{
        "Effect": "Allow",
        "Action": [
          "s3:ListBucket",
          "s3:GetObject",
          "s3:PutObject"
        ],
        "Resource": [
          "arn:aws:s3:::YOUR_BUCKET",
          "arn:aws:s3:::YOUR_BUCKET/*"
        ]
      }]
    }

    Replace YOUR_BUCKET with your bucket name. An import-only user can drop s3:PutObject too. And if the connection test later finds a permission missing, the modal shows this same policy with your bucket name already filled in, next to the exact steps to attach it.

  3. Enter bucket, region and keys, then press Test Connection

    Fifteen AWS regions are supported, from us-east-1 to ap-south-1. The test calls the bucket and tells you exactly what is wrong when something is: an invalid key, a wrong secret, a missing s3:ListBucket permission, a bucket that lives in another region. Test first; a typo dies here instead of in your first sync.

    The AWS Credentials section of the S3 configuration modal: bucket name acme-web-locales, region eu-central-1, and fields for the access key ID and secret access key
    Bucket, region and credentials in one place, with a test that names the exact problem.
  4. Point it at your files

    An optional path prefix, the file format, and how files are named. For import, also the mode: translation files matched by structure, or a glob across whatever the bucket holds, plus the update existing and delete removed switches, both off by default so a first run cannot overwrite or remove a translator’s work.

  5. Save, then push or pull once

    The project’s Synchronisation panel gets a Push button for the export integration and a Pull button for the import one. Run it once and check the result counts; an empty run is a pass too, it means bucket and project already agree.

    The S3 Export card on the Synchronisation panel: bucket s3-i18n-integration-demo in eu-central-1 with a Push button
    Day-to-day home of the integration once it is connected.

Security

One bucket, one user, one policy

The credential is an IAM access key you mint for exactly this purpose, and the modal hands you the policy to mint it with: list, read and write on a single named bucket, nothing else. locamorph never sees your AWS account beyond that bucket, cannot reach another one, and cannot touch anything that is not S3.

The connection is proven before you rely on it. The test does not just fail, it diagnoses: wrong access key, wrong secret, valid credentials with a missing permission, or a bucket that lives in a different region each produce their own message, so you fix the actual problem instead of guessing. After setup the keys stay server-side; editing the integration later means entering a new secret, never reading the old one back.

Revocation belongs to you, in AWS. Deactivate the access key in IAM and the integration stops that instant, no cleanup on our side required. Since import and export are separate integrations, they can carry separate keys: a read-scoped user for the intake bucket, a write-scoped one for the publish bucket, each revocable on its own.

Common workflows

Three shapes teams settle into

For import, the mode switch decides how the bucket is read: files arranged for translation, or files as a pipeline left them.

The import settings: file structure with one file per language previewing en.json, de.json and fr.json, a source pattern import option, and the update existing and delete removed toggles
The intake switch: a locale layout, or a glob across the bucket.

The CDN origin

Export only. The bucket sits behind CloudFront or any CDN, your apps fetch translations at runtime, and a push before each release makes the new strings live. Byte-stable output means caches invalidate only when content actually changed.

The pipeline intake

Import only, usually in glob mode. Upstream systems drop files into a bucket on their own schedule: a legacy exporter, a data pipeline, another team’s tooling. Pull picks up whatever landed, adds the new keys, and leaves existing translations alone.

The split loop

Both directions, different buckets. Sources arrive in a staging bucket from wherever they are produced; finished translations publish to a production bucket the apps read. Separate credentials mean the intake user cannot write where the apps read, and the publish user cannot see the staging data.

Point it at a bucket

Free plan, one IAM user, and a connection test that names the exact problem before anything is saved. If it is not what you hoped, deactivating the key in AWS ends it as cleanly as it began.