Configure
A .quilletrc at the root of your repository tells the CLI which CMS, project, environment and locale to work on, and flags and variables override it for one run.
Why the repository says where its content lives
Almost every command acts on one project and one environment. You could type --api-url, --project and --env on every line, but that is slow, and one slip writes to the wrong place. A small file in the repository says once where the repository's content lives. It goes through review like any other change.
The JavaScript SDK reads the same file. Because a site and the command line that feeds it read one file, they agree on the CMS and the project. The CLI keeps its own settings in a sync section, which the SDK ignores. No secret goes in the file. It is safe to commit.
What the file holds and what overrides it
The CLI finds one settings file, reads its keys and fills in any environment variables the file names, and then lets flags and variables override it for a single run. Whatever the file says, your credential still decides where a command is allowed to write.
The file
The CLI looks for five names, in this order: .quilletrc, .quilletrc.json, quillet.config.js, quillet.config.mjs and quillet.config.ts. It searches the working directory first and then each directory above it, and the first file it finds wins. QUILLET_CONFIG names a file directly. If that file does not exist, the command fails with an error instead of silently falling back to the search. A .quilletrc is JSON. A quillet.config.* file is a module whose default export is the same object.
| Key | Holds | Example |
|---|---|---|
apiUrl |
the CMS's origin, with no path | https://cms.example.com |
project |
the project's slug | handbook |
env |
the environment's key | main |
locale |
the locale commands read and write | en-US |
sync |
the folders this repository manages | see Sync a repository |
The CLI ignores assets, cache, refs and retry, which belong to the SDK. It refuses any other key, and it refuses a key too: a credential belongs in QUILLET_MANAGEMENT_KEY or in quillet login, never in the file. When the file has no locale, a command reads and writes the project's default locale.
Variables inside the file
Any string in the file may hold ${NAME}. When the CLI reads the file, it replaces that with the value of the environment variable of the same name. A variable that is not set is an error; the CLI never substitutes an empty string. QUILLET_MANAGEMENT_KEY, QUILLET_KEY_ID and QUILLET_KEY_SECRET are refused in the file, so a secret can never end up in a value that the CLI prints or sends as the API URL.
This site's own repository relies on that to keep one file for every CMS it is built against. The CMS and the project come from the environment, and the rest is fixed:
{
"apiUrl": "${QUILLET_API_URL}",
"project": "${QUILLET_PROJECT}",
"env": "main",
"locale": "en-US",
"sync": {
"contentDir": "content",
"scope": [
{ "prefix": "docs/" },
{ "prefix": "pages/" },
{ "prefix": "_schemas/" },
{ "prefix": "_singletons/" }
]
}
}
Precedence
When a setting comes from more than one place, the CLI takes it from the highest of these, highest first:
- Flags:
--api-url,--project,--env,--locale. - Variables:
QUILLET_API_URL,QUILLET_PROJECT,QUILLET_ENV,QUILLET_LOCALE. - The file.
A flag may sit before or after the command name. The one typed nearest the command wins. The CLI checks every value before it sends anything. apiUrl must be an origin like https://cms.example.com, and project and env must be slugs of lowercase letters, digits and dashes. When a command needs a value that nobody gave, it names the flag, the variable and the file key that would supply it, and exits with code 2:
No environment. Pass --env, set QUILLET_ENV, or put "env" in .quilletrc.
Keys and environments
A CLI key is bound either to every environment of its project or to just one. A key bound to staging cannot write to main, whatever the file says. The file chooses where you work. The key decides where you may. A personal token reaches every environment of every project you belong to, with your role in each.
How to
Write the file at the root of the repository, filling in your own CMS, project, environment and locale:
cat > .quilletrc <<'EOF'
{
"apiUrl": "<api-url>",
"project": "<project>",
"env": "<env>",
"locale": "<locale>"
}
EOF
Check that it points where you meant. projects show prints the project the file names, with its locales and its limits, and envs list prints that project's environments:
npx quillet projects show
npx quillet envs list
KEY NAME DEFAULT CREATED
main Main yes 2026-10-24T22:48:48.417Z
staging Staging 2026-10-24T22:48:48.420Z
To work on another environment for one command, pass the flag:
npx quillet content list --env <env>
Or set the variable, and every command in this shell uses it:
export QUILLET_ENV=<env>
npx quillet content list
unset QUILLET_ENV puts the file back in charge. npx quillet whoami tells you which credential those commands run with, and which scopes it holds.
Commit the file:
git add .quilletrc
Limits
- One file names one project, and there are no profiles. To work on two projects, use two directories, or pass
--projectfor the second one. quillet initwrites only a JSON.quilletrc. It refuses to edit aquillet.config.*module, so add thesyncsection to a module by hand.- A
${NAME}that is unset fails the command. There is no syntax for a default value. - The file cannot hold a credential, in any form.
- The file creates nothing. The project and the environment it names must already exist; Environments covers creating one.
Related
- Install and sign in: the credential the file never holds.
- Sync a repository: the
syncsection, the folders it names and the lock. - Command reference: the global flags every command takes.
- Configure the SDK: the same file, as a site reads it.
- Environments and promotion: why a project has environments at all.