Store and retrieve static assets with Workers KV
Store and retrieve static assets with Workers KV
By storing static assets in Workers KV, you can retrieve these assets globally with low-latency and high throughput. You can then serve these assets directly, or use them to dynamically generate responses. This can be useful when serving files and images, or when generating dynamic HTML responses from static assets such as translations.
All of the tutorials assume you have already completed the Get started guide, which gets you set up with a Cloudflare Workers account, C3 ↗, and Wrangler.
To get started, create a Worker application using the create-cloudflare
CLI ↗. Open a terminal window and run the following command:
For setup, select the following options:
- For What would you like to start with?, choose
Hello World example
. - For Which template would you like to use?, choose
Hello World Worker
. - For Which language do you want to use?, choose
TypeScript
. - For Do you want to use git for version control?, choose
Yes
. - For Do you want to deploy your application?, choose
No
(we will be making some changes before deploying).
Then, move into your newly created application
We'll also install the dependencies we will need for this project.
Next, we will create a KV store. This can be done through the Cloudflare dashboard or the Wrangler CLI. For this example, we will use the Wrangler CLI.
To create a KV store via Wrangler:
-
Open your terminal and run the following command:
The
wrangler kv namespace create assets
subcommand creates a KV namespace by concatenating your Worker's name and the value provided forassets
. Anid
will be randomly generated for the KV namespace. -
In your
wrangler.toml
file, add the following with the values generated in the terminal:The KV binding
assets
is how your Worker will interact with the KV namespace. This binding will be provided as a runtime variable within your Workers code by the Workers runtime.We'll also create a preview KV namespace. It is recommended to create a separate KV namespace when developing locally to avoid making changes to the production namespace. When developing locally against remote resources, the Wrangler CLI will only use the namespace specified by
preview_id
in the KV namespace configuration of thewrangler.toml
file. -
In your terminal, run the following command:
This command will create a special KV namespace that will be used only when developing with Wrangler against remote resources using
wrangler dev --remote
. -
In your
wrangler.toml
file, add the additional preview_id below kv_namespaces with the values generated in the terminal:
We now have one KV binding that will use the production KV namespace when deployed and the preview KV namespace when developing locally against remote resources with wrangler dev --remote
.
To store static assets in KV, you can use the Wrangler CLI, the KV binding from a Worker application, or the KV REST API. We'll demonstrate how to use the Wrangler CLI.
For this scenario, we'll be storing a sample HTML file within our KV store. Create a new file index.html
in the root of project with the following content:
We can then use the following Wrangler commands to create a KV pair for this file within our production and preview namespaces:
This will create a KV pair with the filename as key and the file content as value, within the our production and preview namespaces specified by your binding in your wrangler.toml
file.
Within the index.ts
file of our Worker project, replace the contents with the following:
This code will use the path within the URL and find the file associated to the path within the KV store. It also sets the proper MIME type in the response to indicate to the browser how to handle the response. To retrieve the value from the KV store, this code uses arrayBuffer
to properly handle binary data such as images, documents, and video/audio files.
To start the Worker, run the following within a terminal:
This will run you Worker code against your remote resources, specifically using the preview KV namespace as configured.
Access the URL provided by the Wrangler command as such http://localhost:<PORT>/index.html
. You will be able to see the returned HTML file containing the file contents of our index.html
file that was added to our KV store. Try it out with an image or a document and you will see that this Worker is also properly serving those assets from KV.
We'll add a hello-world
endpoint to our Workers application, which will return a "Hello World!" message based on the language requested to demonstrate how to generate a dynamic response from our KV-stored assets.
Start by creating this file in the root of your project:
Open a terminal and enter the following KV command to create a KV entry for the translations file:
Update your Workers code to add logic to serve a translated HTML file based on the language of the Accept-Language header of the request:
This new code provides a specific endpoint, /hello-world
, which will provide translated responses. When this URL is accessed, our Worker code will first retrieve the language that is requested by the client in the Accept-Language
request header and the translations from our KV store for the hello-world.json
key. It then gets the translated message and returns the generated HTML.
With the Worker code running, we can notice that our application is now returning the properly translated "Hello World" message. From your browser's developer console, change the locale language (on Chromium browsers, Run Show Sensors
to get a dropdown selection for locales).
Run wrangler deploy
to deploy your Workers project to Cloudflare with the binding to the KV namespace.
Wrangler will automatically set your KV binding to use the production KV namespace set in our wrangler.toml
file with the KV namespace id. Throughout this example, we uploaded our assets to both the preview and the production KV namespaces.
We can now verify that our project is properly working by accessing our Workers default hostname and accessing <WORKER-SUBDOMAIN>.<DEFAULT-ACCOUNT-HOSTNAME>.dev/index.html
or <WORKER-SUBDOMAIN>.<DEFAULT-ACCOUNT-HOSTNAME>.dev/hello-world
to see our deployed Worker in action, generating responses from the values in our KV store.