I'm using Cloudflare Pages with KV.
I'm using Cloudflare Pages with KV.
My goal is to set up KV for different environments, to have:
1. one KV id for production, and
2. another KV id for all other environments (preview URLs, local dev with miniflare maybe, etc)
The docs show two approaches:
v1
OR
v2 (using environments)
- which is preferred and why?
- for the first version, how does Cloudflare differentiate when to use the KV represented by
id
or preview_id
?9 Replies
The docs & ChatGPT weren't helpful.
To figure this out, I:
1. Added production and preview bindings to my Cloudflare Pages project using the Cloudflare dashboard (screenshot).
2. Generated a
wrangler.toml
using bunx wrangler@latest pages download config myproject
, to see what it creates:
I believe that is equivalent toml to this:
1. I assume it only makes sense to use the same binding name for production and preview, so my code works consistently.
2. I assume production applies only when mycustomdomain.com
and any *.pages.dev
is preview.
3. Will the non-production kv_namespace be used for everything that is not production (e.g. CI, local tests, local dev?). Or should I add preview_id="abc123"
to cover those scenarios?
The docs could be improved on this topic.https://developers.cloudflare.com/pages/functions/wrangler-configuration/#environment-specific-overrides
If you wanted to have configuration values apply to local and preview, but override production, your file would look like this:
Appreciate the link. Looks like that's how mine ended up above too. Thanks for the confirmation!
@r2d2 The binding id is what is used when the worker is deployed. The preview_id is used when you're running
wrangler dev
with the --remote
option.
In your case, seems like you've gotten to the right conclusion that environments is the right tool. I'll make sure to clarify the preview_id
in the docs (PR: https://github.com/cloudflare/cloudflare-docs/pull/15978)Thanks @thomasgauvin One more question while you're here: what env is used for
(I'm new to
wrangler dev
when the --remote
option is not provided--a local or dev env I see from your PR? Is it possible to define bindings for local mock versions of R2 & D1 in my wrangler.toml
? Or is KV the only of these that has a local version?(I'm new to
wrangler dev
, so probably a basic question. Not even sure how to get hot reloading yet)No problem, when you use
wrangler dev
, all storage resources will create a local only KV/D1/R2, which are associated to the ids in the binding (ie switching the id in wrangler.toml will switch the local version)
You'll notice that all of the services (R2, D1, KV) have the notice regarding wrangler dev
using the local copy
https://developers.cloudflare.com/r2/api/workers/workers-api-usage/#4-access-your-r2-bucket-from-your-worker
https://developers.cloudflare.com/kv/get-started/#4-access-your-kv-namespace-from-a-worker
https://developers.cloudflare.com/d1/build-with-d1/local-development/#start-a-local-development-sessionThanks again @thomasgauvin Helpful!
Idea: When running the
wrangler pages dev
command, it'd be informative--and reassuring--if it printed out what resource bindings are active. For example:
wrangler pages dev
Active bindings:
- D1: FOO (local)
- KV: BAR (local)
- R2: BAZ (local)
wrangler pages dev --remote
Active bindings:
- D1: FOO (remote: <foo-name>, <id>)
- KV: BAR (remote: <bar-name>, <id>)
- R2: BAZ (remote: <baz-name>, <id>)
or
No bindings. Add to wrangler.toml. Example: <linkShowingEveryResourceSetUpForRemoteAccess>
(Duplicate a bulleted line if there are multiple bindings for a given resource type.)
Another piece of DX feedback: Sticking with just name
and id
for all of these in wrangler.toml
would be more consistent; otherwise I found myself needing to look up what the expected key name is, which isn't needed given each is already scoped by kv_namespaces, r2_buckets, d1_databases, etc.
I take it back--the CLI does output which bindings are active, in much the same way I suggested! lol (Although it doesn't show anything to indicate when no bindings are active, which would help.)
It was just that none of my bindings were active until I passed bunx wrangler pages dev --d1 <binding>
and saw this output for the first time. Thought the bindings would be picked up from my wrangler.toml
like they are for other environments.
Posting in case it helps other searchers:
Summary of environments for Cloudflare Pages, as I've learned:
In wrangler.toml
:
1. [env.production]
specifies bindings for production.
2. Other bindings not within [env.production]
are for preview environment
(i.e. non-production branch, preview URLs).
These resources are also used if wrangler dev --remote
flag is specified.
But wrangler pages dev --remote
does NOT work for remote resources
for Pages projects for D1 as noted in docs (not sure about KV and R1 yet),
and this is fine b/c I don't need or want remote access when a project is run locally.
3. I removed preview_database_id
for D1, preview_id
for KV, and preview_bucket_name
for R2 b/c Pages cannot access a remote D1 database anyway as noted in docs.
5. Locally, run wrangler pages dev --d1 D1 --kv KV --r2 R2 --live-reload
to bind local resources
for KV, R2, and D1. Wrangler will create these after this command is run the first time and their data will be persisted in .wrangler/state/v3
between runs.
(TBD on how to clear our these resources and seed them consistently each time, but I'll figure that out.)
I'd prefer if wrangler set up local bindings automatically based on those inn wrangler.toml
instead of needing to pass them as options to wrangler pages dev --d1 D1 --r2 R2 --kv KV
.
But super happy to have figured this out! Thanks so muchThanks for all this feedback! I want to make some time to read this
TDLR on feedback:
-
wrangler pages dev
should print a message when no bindings are active too, so it's clear to new devs when things are not yet set up properly but they're unaware.
- In wrangler.toml
, consider more consistent naming of id
and name
, within each resource, because they're already scoped within kb_namespaces
, r2_buckets
, & d1_databases
. The current mixed property naming convention (below) means devs needs to check the docs to see what each expects because it's not as consistent/predictable as it could be.
- KV id
- D1 database_id
, database_name
- R2 bucket_name
Thanks for the help earlier!
Update for future searchers: the above env setup will eventually encounter a couple small edge cases. Use the following instead:
And target local/preview/production with these flags: