+
+ >
+ );
+ })
}
diff --git a/src/content/docs/kv/examples/cache-data-with-workers-kv.mdx b/src/content/docs/kv/examples/cache-data-with-workers-kv.mdx
index 4334eea7426fbc..48f201646437a9 100644
--- a/src/content/docs/kv/examples/cache-data-with-workers-kv.mdx
+++ b/src/content/docs/kv/examples/cache-data-with-workers-kv.mdx
@@ -1,8 +1,6 @@
---
type: example
summary: Cache data or API responses in Workers KV to improve application performance
-tags:
- - KV
pcx_content_type: configuration
title: Cache data with Workers KV
sidebar:
diff --git a/src/content/docs/kv/examples/distributed-configuration-with-workers-kv.mdx b/src/content/docs/kv/examples/distributed-configuration-with-workers-kv.mdx
index 27bf6d07291237..845d036b60d278 100644
--- a/src/content/docs/kv/examples/distributed-configuration-with-workers-kv.mdx
+++ b/src/content/docs/kv/examples/distributed-configuration-with-workers-kv.mdx
@@ -1,8 +1,6 @@
---
type: example
summary: Use Workers KV to as a geo-distributed, low-latency configuration store for your Workers application
-tags:
- - KV
pcx_content_type: configuration
title: Build a distributed configuration store
sidebar:
@@ -19,7 +17,7 @@ In this example, application configuration data is used to personalize the Worke
## Write your configuration from your external application to Workers KV
In some cases, your source-of-truth for your configuration data may be stored elsewhere than Workers KV.
-If this is the case, use the Workers KV REST API to write the configuration data to your Workers KV namespace.
+If this is the case, use the Workers KV REST API to write the configuration data to your Workers KV namespace.
The following external Node.js application demonstrates a simple scripts that reads user data from a database and writes it to Workers KV using the REST API library.
@@ -31,8 +29,8 @@ const { Cloudflare } = require('cloudflare');
const { backOff } = require('exponential-backoff');
if(!process.env.DATABASE_CONNECTION_STRING || !process.env.CLOUDFLARE_EMAIL || !process.env.CLOUDFLARE_API_KEY || !process.env.CLOUDFLARE_WORKERS_KV_NAMESPACE_ID || !process.env.CLOUDFLARE_ACCOUNT_ID) {
- console.error('Missing required environment variables.');
- process.exit(1);
+console.error('Missing required environment variables.');
+process.exit(1);
}
// Setup Postgres connection
@@ -40,54 +38,56 @@ const sql = postgres(process.env.DATABASE_CONNECTION_STRING);
// Setup Cloudflare REST API client
const client = new Cloudflare({
- apiEmail: process.env.CLOUDFLARE_EMAIL,
- apiKey: process.env.CLOUDFLARE_API_KEY,
+apiEmail: process.env.CLOUDFLARE_EMAIL,
+apiKey: process.env.CLOUDFLARE_API_KEY,
});
// Function to sync Postgres data to Workers KV
async function syncPreviewStatus() {
- console.log('Starting sync of user preview status...');
-
- try {
- // Get all users and their preview status
- const users = await sql`SELECT id, preview_features_enabled FROM users`;
-
- console.log(users);
-
- // Create the bulk update body
- const bulkUpdateBody = users.map(user => ({
- key: user.id,
- value: JSON.stringify({
- preview_features_enabled: user.preview_features_enabled
- })
- }));
-
- const response = await backOff(async () => {
- console.log("trying to update")
- try{
- const response = await client.kv.namespaces.bulkUpdate(process.env.CLOUDFLARE_WORKERS_KV_NAMESPACE_ID, {
- account_id: process.env.CLOUDFLARE_ACCOUNT_ID,
- body: bulkUpdateBody
- });
- }
- catch(e){
- // Implement your error handling and logging here
- console.log(e);
- throw e; // Rethrow the error to retry
- }
- });
-
- console.log(`Sync complete. Updated ${users.length} users.`);
- } catch (error) {
- console.error('Error syncing preview status:', error);
- }
+console.log('Starting sync of user preview status...');
+
+ try {
+ // Get all users and their preview status
+ const users = await sql`SELECT id, preview_features_enabled FROM users`;
+
+ console.log(users);
+
+ // Create the bulk update body
+ const bulkUpdateBody = users.map(user => ({
+ key: user.id,
+ value: JSON.stringify({
+ preview_features_enabled: user.preview_features_enabled
+ })
+ }));
+
+ const response = await backOff(async () => {
+ console.log("trying to update")
+ try{
+ const response = await client.kv.namespaces.bulkUpdate(process.env.CLOUDFLARE_WORKERS_KV_NAMESPACE_ID, {
+ account_id: process.env.CLOUDFLARE_ACCOUNT_ID,
+ body: bulkUpdateBody
+ });
+ }
+ catch(e){
+ // Implement your error handling and logging here
+ console.log(e);
+ throw e; // Rethrow the error to retry
+ }
+ });
+
+ console.log(`Sync complete. Updated ${users.length} users.`);
+ } catch (error) {
+ console.error('Error syncing preview status:', error);
+ }
+
}
// Run the sync function
syncPreviewStatus()
- .catch(console.error)
- .finally(() => process.exit(0));
-```
+.catch(console.error)
+.finally(() => process.exit(0));
+
+````
```md title=".env"
@@ -225,7 +225,7 @@ This code will use the path within the URL and find the file associated to the p
## Optimize performance for configuration
-To optimize performance, you may opt to consolidate values in fewer key-value pairs. By doing so, you may benefit from higher caching efficiency and lower latency.
+To optimize performance, you may opt to consolidate values in fewer key-value pairs. By doing so, you may benefit from higher caching efficiency and lower latency.
For example, instead of storing each user's configuration in a separate key-value pair, you may store all users' configurations in a single key-value pair. This approach may be suitable for use-cases where the configuration data is small and can be easily managed in a single key-value pair (the [size limit for a Workers KV value is 25 MiB](/kv/platform/limits/)).
diff --git a/src/content/docs/kv/examples/implement-ab-testing-with-workers-kv.mdx b/src/content/docs/kv/examples/implement-ab-testing-with-workers-kv.mdx
index 29fcaf903f8df8..24574e77d53ad7 100644
--- a/src/content/docs/kv/examples/implement-ab-testing-with-workers-kv.mdx
+++ b/src/content/docs/kv/examples/implement-ab-testing-with-workers-kv.mdx
@@ -1,11 +1,9 @@
---
type: example
summary: Use Workers KV to store A/B testing configuration data and analyze the performance of different versions of your website
-tags:
- - KV
pcx_content_type: configuration
title: A/B testing with Workers KV
external_link: /reference-architecture/diagrams/serverless/a-b-testing-using-workers/
sidebar:
order: 6
----
\ No newline at end of file
+---
diff --git a/src/content/docs/kv/examples/routing-with-workers-kv.mdx b/src/content/docs/kv/examples/routing-with-workers-kv.mdx
index b386908a23bd10..ba4598135d690b 100644
--- a/src/content/docs/kv/examples/routing-with-workers-kv.mdx
+++ b/src/content/docs/kv/examples/routing-with-workers-kv.mdx
@@ -1,8 +1,6 @@
---
type: example
summary: Store routing data in Workers KV to route requests across various web servers with Workers
-tags:
- - KV
pcx_content_type: configuration
title: Route requests across various web servers
sidebar:
@@ -16,7 +14,6 @@ Using Workers KV to store routing data to route requests across various web serv
Routing can be helpful to route requests coming into a single Cloudflare Worker application to different web servers based on the request's path, hostname, or other request attributes.
-
In single-tenant applications, this can be used to route requests to various origin servers based on the business domain (for example, requests to `/admin` routed to administration server, `/store` routed to storefront server, `/api` routed to the API server).
In multi-tenant applications, requests can be routed to the tenant's respective origin resources (for example, requests to `tenantA.your-worker-hostname.com` routed to server for Tenant A, `tenantB.your-worker-hostname.com` routed to server for Tenant B).
@@ -142,7 +139,6 @@ In this example, the Cloudflare Worker receives a request and extracts the store
The storefront ID is used to look up the origin server URL from Workers KV using the `get()` method.
The request is then forwarded to the origin server, and the response is modified to include custom headers before being returned to the client.
-
## Related resources
- [Rust support in Workers](/workers/languages/rust/).
diff --git a/src/content/docs/kv/examples/workers-kv-to-serve-assets.mdx b/src/content/docs/kv/examples/workers-kv-to-serve-assets.mdx
index 293d300879fa59..8d329c9d38f29e 100644
--- a/src/content/docs/kv/examples/workers-kv-to-serve-assets.mdx
+++ b/src/content/docs/kv/examples/workers-kv-to-serve-assets.mdx
@@ -1,8 +1,6 @@
---
type: example
summary: Store static assets in Workers KV and serve them from a Worker application with low-latency and high-throughput
-tags:
- - KV
pcx_content_type: configuration
title: Store and retrieve static assets
sidebar:
diff --git a/src/content/docs/style-guide/frontmatter/tags.mdx b/src/content/docs/style-guide/frontmatter/tags.mdx
index 6dd5ce4fe3d3ea..c0c657c28dc29b 100644
--- a/src/content/docs/style-guide/frontmatter/tags.mdx
+++ b/src/content/docs/style-guide/frontmatter/tags.mdx
@@ -6,7 +6,7 @@ import { TagsUsage } from "~/components";
Tags are currently used to filter content in the [`ExternalResources`](/style-guide/components/external-resources/), [`ProductsByTag`](/style-guide/components/products-by-tag/) and the [`ResourcesBySelector`](/style-guide/components/resources-by-selector/) components.
-## Examples
+## Example
```mdx
---
@@ -17,6 +17,15 @@ tags:
---
```
-## Tags
+## Allowed tags and where they are being used
-
\ No newline at end of file
+Tags are validated against an allowlist in [`/src/schemas/tags.ts`](https://github.com/cloudflare/cloudflare-docs/blob/production/src/schemas/tags.ts) which defines the user-facing representation (`label`) and any associated variants.
+
+The matching is case-insensitive. For example, all of the following values are accepted in the `tags` frontmatter array and will be transformed into `Node.js`:
+
+- `node.js`
+- `NoDe.JS`
+- `node`
+- `nodejs`
+
+
diff --git a/src/plugins/starlight/route-data.ts b/src/plugins/starlight/route-data.ts
new file mode 100644
index 00000000000000..5264b712052574
--- /dev/null
+++ b/src/plugins/starlight/route-data.ts
@@ -0,0 +1,29 @@
+import { defineRouteMiddleware } from "@astrojs/starlight/route-data";
+import { tags as allowedTags } from "~/schemas/tags";
+
+export const onRequest = defineRouteMiddleware(({ locals }) => {
+ const { entry } = locals.starlightRoute;
+ const { tags } = entry.data;
+
+ if (tags) {
+ const transformed = tags.map((tag) => {
+ const values = Object.values(allowedTags).flat();
+
+ const match = values.find(
+ (val) =>
+ val.label.toLowerCase() === tag.toLowerCase() ||
+ val.variants?.find((v) => v.toLowerCase() === tag.toLowerCase()),
+ );
+
+ if (!match) {
+ throw new Error(
+ `Invalid tag on ${entry.id}: ${tag}, please refer to the style guide: https://developers.cloudflare.com/style-guide/frontmatter/tags/`,
+ );
+ }
+
+ return match.label;
+ });
+
+ entry.data.tags = transformed;
+ }
+});
diff --git a/src/schemas/tags.ts b/src/schemas/tags.ts
index 6ea693d0b2b5aa..268e660ad3320e 100644
--- a/src/schemas/tags.ts
+++ b/src/schemas/tags.ts
@@ -3,14 +3,16 @@ in our page frontmatter. Refer to https://developers.cloudflare.com/style-guide/
and https://developers.cloudflare.com/style-guide/frontmatter/tags/ for more details.
*/
-const data_structures: Array