How to replace a value per environment
Sometimes a piece of metadata must hold a different value in each stage org — an endpoint URL, a
named-credential principal, a running user, a certificate name. Value replacements handle this:
a Salesforce CLI source-behavior feature driven by a replacements block in sfdx-project.json,
which the toolchain feeds only by setting SF_DEPLOY_TARGET to the stage it deploys to (see
the branch, environment and org model).
Add a replacement
Add a replacements array to sfdx-project.json. Each entry names what to find, what to put there,
and — optionally — the condition under which it applies:
{
"packageDirectories": [{ "path": "force-app", "default": true }],
"sourceApiVersion": "66.0",
"replacements": [
{
"filename": "force-app/main/default/namedCredentials/My_API.namedCredential-meta.xml",
"stringToReplace": "https://placeholder.example.com",
"replaceWithFile": "config/replacements/my-api-endpoint.uat.txt",
"replaceWhenEnv": [{ "env": "SF_DEPLOY_TARGET", "value": "UAT" }]
}
]
}
On any deploy or push where SF_DEPLOY_TARGET is UAT, sf replaces the placeholder string in that
file with the contents of the replacement file. Add one entry per (file, stage) pair you need.
Key it on the deploy target
The pipeline sets SF_DEPLOY_TARGET to the upper-cased stage name for the org it is deploying
to, and falls back to SIT for scratch-org and local runs (see the
environment variable reference and
the branch/org model). So:
- Use
SIT,UAT,PRODUCTION(upper-case) as thereplaceWhenEnvvalues — they must match the stage names the pipeline produces. - A replacement with no
replaceWhenEnvapplies on every deploy. - Because the default is
SIT, avalue: "SIT"entry also covers scratch orgs and local pushes.
Other forms
regex, replaceWithEnv, glob and the rest of the schema are in the Salesforce DX Developer
Guide: Replace Strings in Code and Metadata.
Verify
Set SF_DEPLOY_TARGET to the stage you want to check in your shell, then run a validate-only deploy
against a scratch org or a stage and confirm the value that landed:
deploy:validate runs the orchestrator's workarounds — custom pre/post deployment hooks are skipped
in validate mode — as a check-only, dry-run deploy. Inspect the generated output, or deploy for real
and check the component in the org. If the value did not change, check that replaceWhenEnv matches
the SF_DEPLOY_TARGET in play and that the file path or glob actually matches the component.
Do not call sf project deploy directly
Calling the Salesforce CLI's own deploy command bypasses the orchestrator — no workarounds, no
delta logic. Verify replacements through npm run deploy:validate.
Replacement files are committed in clear text
replaceWithFile reads a tracked file in the repo. Do not put secrets there — use
replaceWithEnv pointing at a secured repository variable for anything sensitive.