diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/access-group.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/access-group.mdx
index 12ec3662c3b016..3c39aa06531028 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/access-group.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/access-group.mdx
@@ -1,20 +1,17 @@
---
type: example
summary: Use a pre-existing rule group.
-tags:
- - Rule group
title: Rule group
pcx_content_type: example
sidebar:
order: 4
description: Use a pre-existing rule group.
-
---
```json
{
- "group": {
- "id": "aa0a4aab-672b-4bdb-bc33-a59f1130a11f"
- }
+ "group": {
+ "id": "aa0a4aab-672b-4bdb-bc33-a59f1130a11f"
+ }
}
```
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/any-service-token.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/any-service-token.mdx
index 35f51d16168c0e..d96d19cfe9c423 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/any-service-token.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/any-service-token.mdx
@@ -2,21 +2,18 @@
type: example
summary: The request will need to present the headers for any service token
created for this account.
-tags:
- - Any valid service token
title: Any valid service token
pcx_content_type: example
sidebar:
order: 4
description: The request will need to present the headers for any service token
created for this account.
-
---
The request will need to present the headers for any service token created for this account
```json
{
- "any_valid_service_token": {}
+ "any_valid_service_token": {}
}
```
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/authentication-method.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/authentication-method.mdx
index 3e3f465c4eface..90e41b2c4b725f 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/authentication-method.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/authentication-method.mdx
@@ -1,20 +1,17 @@
---
type: example
summary: Allow access based on the "amr" identifier.
-tags:
- - Authentication Method
title: Authentication method
pcx_content_type: example
sidebar:
order: 4
description: Allow access based on the "amr" identifier.
-
---
```json
{
- "auth_method": {
- "auth_method": "hwk"
- }
+ "auth_method": {
+ "auth_method": "hwk"
+ }
}
```
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/common-name.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/common-name.mdx
index bc0ba9723d14aa..77d8db31ea214b 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/common-name.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/common-name.mdx
@@ -2,21 +2,18 @@
type: example
summary: The request will need to present a valid certificate with an expected
common name.
-tags:
- - Common name
title: Common name
pcx_content_type: example
sidebar:
order: 4
description: The request will need to present a valid certificate with an
expected common name.
-
---
```json
{
- "common_name": {
- "common_name": "james@example.com"
- }
+ "common_name": {
+ "common_name": "james@example.com"
+ }
}
```
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/country-code.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/country-code.mdx
index 8d53041ab7b7e4..1d69829dca0838 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/country-code.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/country-code.mdx
@@ -1,20 +1,17 @@
---
type: example
summary: Allow a specific country.
-tags:
- - Country Code
title: Country Code
pcx_content_type: example
sidebar:
order: 4
description: Allow a specific country.
-
---
```json
{
- "geo": {
- "country_code": "US"
- }
+ "geo": {
+ "country_code": "US"
+ }
}
```
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/email-domain.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/email-domain.mdx
index dc80389e2b5722..63ee5d6dfc24e5 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/email-domain.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/email-domain.mdx
@@ -1,20 +1,17 @@
---
type: example
summary: Allow an entire email domain.
-tags:
- - Email domain
title: Email domain
pcx_content_type: example
sidebar:
order: 4
description: Allow an entire email domain.
-
---
```json
{
- "email_domain": {
- "domain": "cloudflare.com"
- }
+ "email_domain": {
+ "domain": "cloudflare.com"
+ }
}
```
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/email.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/email.mdx
index dd06a7db4f7b0f..e6f5d3b7c7c9a6 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/email.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/email.mdx
@@ -1,20 +1,17 @@
---
type: example
summary: Allow a specific email address.
-tags:
- - Email
title: Email
pcx_content_type: example
sidebar:
order: 4
description: Allow a specific email address.
-
---
```json
{
- "email": {
- "email": "james@example.com"
- }
+ "email": {
+ "email": "james@example.com"
+ }
}
```
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/entra-group.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/entra-group.mdx
index 0bfd23afa61a5f..15fc60dab496b7 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/entra-group.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/entra-group.mdx
@@ -1,8 +1,6 @@
---
type: example
summary: Allow members of a Microsoft Entra group. The ID is the group UUID (`id`) in Microsoft Entra ID.
-tags:
- - Microsoft Entra Group
title: Microsoft Entra Group
pcx_content_type: example
sidebar:
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/everyone.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/everyone.mdx
index 74dd0cff432468..b35cdab96372df 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/everyone.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/everyone.mdx
@@ -1,18 +1,15 @@
---
type: example
summary: Allow anyone to log in.
-tags:
- - Everyone
title: Everyone
pcx_content_type: example
sidebar:
order: 4
description: Allow anyone to log in.
-
---
```json
{
- "everyone": {}
+ "everyone": {}
}
```
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/github-org.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/github-org.mdx
index ee43dba8acc0e2..b6fac385d91067 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/github-org.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/github-org.mdx
@@ -1,8 +1,6 @@
---
type: example
summary: Allow members of a specific GitHub organization.
-tags:
- - GitHub Organization
title: GitHub™ Organization
pcx_content_type: example
sidebar:
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/gsuite-group.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/gsuite-group.mdx
index 6879330cf99b38..6407ec064f42a3 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/gsuite-group.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/gsuite-group.mdx
@@ -1,8 +1,6 @@
---
type: example
summary: Allow members of a specific G Suite group.
-tags:
- - G Suite Group
title: G Suite Group
pcx_content_type: example
sidebar:
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/ip-range.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/ip-range.mdx
index 5f5f0f00ed90ee..b5fd679eeda17b 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/ip-range.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/ip-range.mdx
@@ -1,20 +1,17 @@
---
type: example
summary: Allow an IP range.
-tags:
- - IP range
title: IP range
pcx_content_type: example
sidebar:
order: 4
description: Allow an IP range.
-
---
```json
{
- "ip": {
- "ip": "127.0.0.1/32"
- }
+ "ip": {
+ "ip": "127.0.0.1/32"
+ }
}
```
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/mtls-certificate.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/mtls-certificate.mdx
index 2535e33ae76419..58565971d8c779 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/mtls-certificate.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/mtls-certificate.mdx
@@ -1,18 +1,15 @@
---
type: example
summary: The request will need to present a valid certificate.
-tags:
- - mTLS certificate
title: mTLS certificate
pcx_content_type: example
sidebar:
order: 4
description: The request will need to present a valid certificate.
-
---
```json
{
- "certificate": {}
+ "certificate": {}
}
```
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/okta-group.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/okta-group.mdx
index d51cd6ca3cea3a..943ab43e2223a7 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/okta-group.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/okta-group.mdx
@@ -1,8 +1,6 @@
---
type: example
summary: Allow members of an Okta Group.
-tags:
- - Okta Group
title: Okta Group
pcx_content_type: example
sidebar:
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/saml-attribute.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/saml-attribute.mdx
index 102cd109de8278..5a4b15abbf4453 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/saml-attribute.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/saml-attribute.mdx
@@ -1,22 +1,19 @@
---
type: example
summary: Allow users with specific SAML attributes.
-tags:
- - SAML Attribute
title: SAML Attribute
pcx_content_type: example
sidebar:
order: 4
description: Allow users with specific SAML attributes.
-
---
```json
{
- "saml": {
- "attribute_name": "group",
- "attribute_value": "admins",
- "identity_provider_id": "ca298b82-93b5-41bf-bc2d-10493f09b761"
- }
+ "saml": {
+ "attribute_name": "group",
+ "attribute_value": "admins",
+ "identity_provider_id": "ca298b82-93b5-41bf-bc2d-10493f09b761"
+ }
}
```
diff --git a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/service-token.mdx b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/service-token.mdx
index 5437ba78b56790..2b449f6b54a7f9 100644
--- a/src/content/docs/cloudflare-one/api-terraform/access-api-examples/service-token.mdx
+++ b/src/content/docs/cloudflare-one/api-terraform/access-api-examples/service-token.mdx
@@ -1,20 +1,17 @@
---
type: example
summary: The request will need to present the correct service token headers.
-tags:
- - Service token
title: Service token
pcx_content_type: example
sidebar:
order: 4
description: The request will need to present the correct service token headers.
-
---
```json
{
- "service_token": {
- "token_id": "e9808c3a-705c-4afc-a507-6e4b083ff399"
- }
+ "service_token": {
+ "token_id": "e9808c3a-705c-4afc-a507-6e4b083ff399"
+ }
}
```
diff --git a/src/content/docs/d1/examples/d1-and-hono.mdx b/src/content/docs/d1/examples/d1-and-hono.mdx
index 52fe30888509aa..0552626134e146 100644
--- a/src/content/docs/d1/examples/d1-and-hono.mdx
+++ b/src/content/docs/d1/examples/d1-and-hono.mdx
@@ -3,24 +3,22 @@ type: example
summary: Query D1 from the Hono web framework
tags:
- Hono
- - D1
pcx_content_type: example
title: Query D1 from Hono
sidebar:
order: 3
description: Query D1 from the Hono web framework
-
---
-import { TabItem, Tabs } from "~/components"
+import { TabItem, Tabs } from "~/components";
Hono is a fast web framework for building API-first applications, and it includes first-class support for both [Workers](/workers/) and [Pages](/pages/).
When using Workers:
-* Ensure you have configured your [Wrangler configuration file](/d1/get-started/#3-bind-your-worker-to-your-d1-database) to bind your D1 database to your Worker.
-* You can access your D1 databases via Hono's [`Context`](https://hono.dev/api/context) parameter: [bindings](https://hono.dev/getting-started/cloudflare-workers#bindings) are exposed on `context.env`. If you configured a [binding](/pages/functions/bindings/#d1-databases) named `DB`, then you would access [D1 Workers Binding API](/d1/worker-api/prepared-statements/) methods via `c.env.DB`.
-* Refer to the Hono documentation for [Cloudflare Workers](https://hono.dev/getting-started/cloudflare-workers).
+- Ensure you have configured your [Wrangler configuration file](/d1/get-started/#3-bind-your-worker-to-your-d1-database) to bind your D1 database to your Worker.
+- You can access your D1 databases via Hono's [`Context`](https://hono.dev/api/context) parameter: [bindings](https://hono.dev/getting-started/cloudflare-workers#bindings) are exposed on `context.env`. If you configured a [binding](/pages/functions/bindings/#d1-databases) named `DB`, then you would access [D1 Workers Binding API](/d1/worker-api/prepared-statements/) methods via `c.env.DB`.
+- Refer to the Hono documentation for [Cloudflare Workers](https://hono.dev/getting-started/cloudflare-workers).
If you are using [Pages Functions](/pages/functions/):
@@ -37,24 +35,24 @@ import { Hono } from "hono";
// This ensures c.env.DB is correctly typed
type Bindings = {
- DB: D1Database;
+ DB: D1Database;
};
const app = new Hono<{ Bindings: Bindings }>();
// Accessing D1 is via the c.env.YOUR_BINDING property
app.get("/query/users/:id", async (c) => {
- const userId = c.req.param("id");
- try {
- let { results } = await c.env.DB.prepare(
- "SELECT * FROM users WHERE user_id = ?",
- )
- .bind(userId)
- .all();
- return c.json(results);
- } catch (e) {
- return c.json({ err: e.message }, 500);
- }
+ const userId = c.req.param("id");
+ try {
+ let { results } = await c.env.DB.prepare(
+ "SELECT * FROM users WHERE user_id = ?",
+ )
+ .bind(userId)
+ .all();
+ return c.json(results);
+ } catch (e) {
+ return c.json({ err: e.message }, 500);
+ }
});
// Export our Hono app: Hono automatically exports a
@@ -72,17 +70,17 @@ const app = new Hono().basePath("/api");
// Accessing D1 is via the c.env.YOUR_BINDING property
app.get("/query/users/:id", async (c) => {
- const userId = c.req.param("id");
- try {
- let { results } = await c.env.DB.prepare(
- "SELECT * FROM users WHERE user_id = ?",
- )
- .bind(userId)
- .all();
- return c.json(results);
- } catch (e) {
- return c.json({ err: e.message }, 500);
- }
+ const userId = c.req.param("id");
+ try {
+ let { results } = await c.env.DB.prepare(
+ "SELECT * FROM users WHERE user_id = ?",
+ )
+ .bind(userId)
+ .all();
+ return c.json(results);
+ } catch (e) {
+ return c.json({ err: e.message }, 500);
+ }
});
// Export the Hono instance as a Pages onRequest function
diff --git a/src/content/docs/d1/examples/d1-and-remix.mdx b/src/content/docs/d1/examples/d1-and-remix.mdx
index 884afaad5fc09f..f61b7bb83ad2a0 100644
--- a/src/content/docs/d1/examples/d1-and-remix.mdx
+++ b/src/content/docs/d1/examples/d1-and-remix.mdx
@@ -3,16 +3,14 @@ type: example
summary: Query your D1 database from a Remix application.
tags:
- Remix
- - D1
pcx_content_type: example
title: Query D1 from Remix
sidebar:
order: 2
description: Query your D1 database from a Remix application.
-
---
-import { TabItem, Tabs } from "~/components"
+import { TabItem, Tabs } from "~/components";
Remix is a full-stack web framework that operates on both client and server. You can query your D1 database(s) from Remix using Remix's [data loading](https://remix.run/docs/en/main/guides/data-loading) API with the [`useLoaderData`](https://remix.run/docs/en/main/hooks/use-loader-data) hook.
@@ -24,8 +22,8 @@ To set up a new Remix site on Cloudflare Pages that can query D1:
The following example shows you how to define a Remix [`loader`](https://remix.run/docs/en/main/route/loader) that has a binding to a D1 database.
-* Bindings are passed through on the `context.env` parameter passed to a `LoaderFunction`.
-* If you configured a [binding](/pages/functions/bindings/#d1-databases) named `DB`, then you would access [D1 Workers Binding API](/d1/worker-api/prepared-statements/) methods via `context.env.DB`.
+- Bindings are passed through on the `context.env` parameter passed to a `LoaderFunction`.
+- If you configured a [binding](/pages/functions/bindings/#d1-databases) named `DB`, then you would access [D1 Workers Binding API](/d1/worker-api/prepared-statements/) methods via `context.env.DB`.
diff --git a/src/content/docs/d1/examples/d1-and-sveltekit.mdx b/src/content/docs/d1/examples/d1-and-sveltekit.mdx
index c7ae97a184f723..6482cb36ce087f 100644
--- a/src/content/docs/d1/examples/d1-and-sveltekit.mdx
+++ b/src/content/docs/d1/examples/d1-and-sveltekit.mdx
@@ -4,16 +4,14 @@ summary: Query a D1 database from a SvelteKit application.
tags:
- SvelteKit
- Svelte
- - D1
pcx_content_type: example
title: Query D1 from SvelteKit
sidebar:
order: 3
description: Query a D1 database from a SvelteKit application.
-
---
-import { TabItem, Tabs } from "~/components"
+import { TabItem, Tabs } from "~/components";
[SvelteKit](https://kit.svelte.dev/) is a full-stack framework that combines the Svelte front-end framework with Vite for server-side capabilities and rendering. You can query D1 from SvelteKit by configuring a [server endpoint](https://kit.svelte.dev/docs/routing#server) with a binding to your D1 database(s).
@@ -26,8 +24,8 @@ To set up a new SvelteKit site on Cloudflare Pages that can query D1:
The following example shows you how to create a server endpoint configured to query D1.
-* Bindings are available on the `platform` parameter passed to each endpoint, via `platform.env.BINDING_NAME`.
-* With SvelteKit's [file-based routing](https://kit.svelte.dev/docs/routing), the server endpoint defined in `src/routes/api/users/+server.ts` is available at `/api/users` within your SvelteKit app.
+- Bindings are available on the `platform` parameter passed to each endpoint, via `platform.env.BINDING_NAME`.
+- With SvelteKit's [file-based routing](https://kit.svelte.dev/docs/routing), the server endpoint defined in `src/routes/api/users/+server.ts` is available at `/api/users` within your SvelteKit app.
The example also shows you how to configure both your app-wide types within `src/app.d.ts` to recognize your `D1Database` binding, import the `@sveltejs/adapter-cloudflare` adapter into `svelte.config.js`, and configure it to apply to all of your routes.
@@ -38,10 +36,10 @@ import type { RequestHandler } from "@sveltejs/kit";
/** @type {import('@sveltejs/kit').RequestHandler} */
export async function GET({ request, platform }) {
- let result = await platform.env.DB.prepare(
- "SELECT * FROM users LIMIT 5"
- ).run();
- return new Response(JSON.stringify(result));
+ let result = await platform.env.DB.prepare(
+ "SELECT * FROM users LIMIT 5",
+ ).run();
+ return new Response(JSON.stringify(result));
}
```
@@ -49,40 +47,39 @@ export async function GET({ request, platform }) {
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
- namespace App {
- // interface Error {}
- // interface Locals {}
- // interface PageData {}
- interface Platform {
- env: {
- DB: D1Database;
- };
- context: {
- waitUntil(promise: Promise): void;
- };
- caches: CacheStorage & { default: Cache };
- }
- }
+ namespace App {
+ // interface Error {}
+ // interface Locals {}
+ // interface PageData {}
+ interface Platform {
+ env: {
+ DB: D1Database;
+ };
+ context: {
+ waitUntil(promise: Promise): void;
+ };
+ caches: CacheStorage & { default: Cache };
+ }
+ }
}
export {};
```
```js
-import adapter from '@sveltejs/adapter-cloudflare';
+import adapter from "@sveltejs/adapter-cloudflare";
export default {
- kit: {
- adapter: adapter({
- // See below for an explanation of these options
- routes: {
- include: ['/*'],
- exclude: ['']
- }
- })
- }
+ kit: {
+ adapter: adapter({
+ // See below for an explanation of these options
+ routes: {
+ include: ["/*"],
+ exclude: [""],
+ },
+ }),
+ },
};
-
```
diff --git a/src/content/docs/d1/examples/query-d1-from-python-workers.mdx b/src/content/docs/d1/examples/query-d1-from-python-workers.mdx
index 112aaebd81e514..712e9929c7d8a9 100644
--- a/src/content/docs/d1/examples/query-d1-from-python-workers.mdx
+++ b/src/content/docs/d1/examples/query-d1-from-python-workers.mdx
@@ -1,9 +1,8 @@
---
type: example
summary: Learn how to query D1 from a Python Worker
-tags:
+languages:
- Python
- - D1
pcx_content_type: example
title: Query D1 from Python Workers
sidebar:
diff --git a/src/content/docs/pages/functions/examples/cors-headers.mdx b/src/content/docs/pages/functions/examples/cors-headers.mdx
index 94fc04159c2e65..3e1e9656bbe0f3 100644
--- a/src/content/docs/pages/functions/examples/cors-headers.mdx
+++ b/src/content/docs/pages/functions/examples/cors-headers.mdx
@@ -2,13 +2,12 @@
type: example
summary: A Pages Functions for appending CORS headers.
tags:
- - CORS
+ - Headers
pcx_content_type: configuration
title: Adding CORS headers
sidebar:
order: 1002
description: A Pages Functions for appending CORS headers.
-
---
This example is a snippet from our Cloudflare Pages Template repo.
@@ -16,23 +15,22 @@ This example is a snippet from our Cloudflare Pages Template repo.
```ts
// Respond to OPTIONS method
export const onRequestOptions: PagesFunction = async () => {
- return new Response(null, {
- status: 204,
- headers: {
- 'Access-Control-Allow-Origin': '*',
- 'Access-Control-Allow-Headers': '*',
- 'Access-Control-Allow-Methods': 'GET, OPTIONS',
- 'Access-Control-Max-Age': '86400',
- },
- });
+ return new Response(null, {
+ status: 204,
+ headers: {
+ "Access-Control-Allow-Origin": "*",
+ "Access-Control-Allow-Headers": "*",
+ "Access-Control-Allow-Methods": "GET, OPTIONS",
+ "Access-Control-Max-Age": "86400",
+ },
+ });
};
// Set CORS to all /api responses
export const onRequest: PagesFunction = async (context) => {
- const response = await context.next();
- response.headers.set('Access-Control-Allow-Origin', '*');
- response.headers.set('Access-Control-Max-Age', '86400');
- return response;
+ const response = await context.next();
+ response.headers.set("Access-Control-Allow-Origin", "*");
+ response.headers.set("Access-Control-Max-Age", "86400");
+ return response;
};
-
```
diff --git a/src/content/docs/pages/migrations/migrating-from-firebase.mdx b/src/content/docs/pages/migrations/migrating-from-firebase.mdx
index 4b6b91bacb7cf3..1459f28382f5b2 100644
--- a/src/content/docs/pages/migrations/migrating-from-firebase.mdx
+++ b/src/content/docs/pages/migrations/migrating-from-firebase.mdx
@@ -3,9 +3,6 @@ updated: 2020-09-28
difficulty: Beginner
pcx_content_type: tutorial
title: Migrating from Firebase
-tags:
- - Firebase
-
---
In this tutorial, you will learn how to migrate an existing Firebase application to Cloudflare Pages. You should already have an existing project deployed on Firebase that you would like to host on Cloudflare Pages.
@@ -18,7 +15,7 @@ You will use these to tell Cloudflare Pages how to deploy your project. If you h
```json title="firebase.json"
{
- "public": "public"
+ "public": "public"
}
```
diff --git a/src/content/docs/pages/migrations/migrating-jekyll-from-github-pages.mdx b/src/content/docs/pages/migrations/migrating-jekyll-from-github-pages.mdx
index 9b25d5811d93e5..a0e1b5ec7ef1b1 100644
--- a/src/content/docs/pages/migrations/migrating-jekyll-from-github-pages.mdx
+++ b/src/content/docs/pages/migrations/migrating-jekyll-from-github-pages.mdx
@@ -3,8 +3,6 @@ updated: 2021-07-27
difficulty: Beginner
pcx_content_type: tutorial
title: Migrating a Jekyll-based site from GitHub Pages
-tags:
- - Jekyll
languages:
- Ruby
---
@@ -49,7 +47,7 @@ Your existing Jekyll-based repository must specify a `Gemfile` (Ruby's dependenc
Specifically, you will need to create a `Gemfile` and install the `github-pages` gem, which includes all of the dependencies that the GitHub Pages environment assumes.
-[Version 2 of the Pages build environment](/pages/configuration/build-image/#languages-and-runtime) will use Ruby 3.2.2 for the default Jekyll build. Please make sure your local development environment is compatible.
+[Version 2 of the Pages build environment](/pages/configuration/build-image/#languages-and-runtime) will use Ruby 3.2.2 for the default Jekyll build. Please make sure your local development environment is compatible.
```sh title="Set Ruby Version"
brew install ruby@3.2
diff --git a/src/content/docs/turnstile/tutorials/integrating-turnstile-waf-and-bot-management.mdx b/src/content/docs/turnstile/tutorials/integrating-turnstile-waf-and-bot-management.mdx
index 87bff40cff208d..4cfe3db44b46f7 100644
--- a/src/content/docs/turnstile/tutorials/integrating-turnstile-waf-and-bot-management.mdx
+++ b/src/content/docs/turnstile/tutorials/integrating-turnstile-waf-and-bot-management.mdx
@@ -4,15 +4,13 @@ pcx_content_type: tutorial
updated: 2024-09-17
difficulty: Beginner
content_type: 📝 Tutorial
-tags:
- - Turnstile
+products:
- Web Application Firewall
- Bot Management
languages:
- JavaScript
sidebar:
order: 3
-
---
This tutorial will guide you on how to integrate Cloudflare Turnstile, [Web Application Firewall (WAF)](/waf/), and [Bot Management](/bots/get-started/bm-subscription/) into an existing authentication system. This combination creates a robust defense against various threats, including automated attacks and malicious login attempts.
@@ -46,11 +44,10 @@ If your site is on Cloudflare's network and subscribed to an Enterprise plan, yo
2. Go to **Security** > **WAF**.
3. Create a new custom WAF rule by selecting "Edit expression":
- Field: "Bot Score"
- - Operator: "less than or equal to"
- - Value: "30"
+ - Operator: "less than or equal to"
+ - Value: "30"
- Action: "Managed Challenge"
-
This configuration challenges requests with a low bot score, leveraging network signals to identify potential threats before they reach your application. You may customize the score threshold based on your specific use case.
## Set up Cloudflare Turnstile
@@ -65,7 +62,6 @@ Turnstile can be used on any site, regardless of whether it is on Cloudflare's n
Turnstile adds an extra layer of security by analyzing browser and client-side signals, complementing the server-side checks performed by WAF and Bot Management.
-
### Enable the option to use the existing clearance cookie
If your site is on Cloudflare, you can enable the option to use the existing [clearance cookie](/turnstile/concepts/pre-clearance-support/) in Turnstile's settings. This integration allows Turnstile to use the clearance cookie as part of its determination of whether a user should receive a challenge. This integration is optional, but recommended if you already are using WAF and Bot Management.
@@ -80,72 +76,85 @@ Add the Turnstile widget to your existing login form:
```html
-
+
```
Replace `YOUR_SITE_KEY` with your actual Turnstile site key.
-
## Handle the login request
In your existing authentication route, add Turnstile validation:
```typescript
-async function validateTurnstileToken(ip: string, token: string, secret: string): Promise {
- const response = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ ip, secret, response: token })
- });
-
- const outcome = await response.json();
- return outcome.success;
+async function validateTurnstileToken(
+ ip: string,
+ token: string,
+ secret: string,
+): Promise {
+ const response = await fetch(
+ "https://challenges.cloudflare.com/turnstile/v0/siteverify",
+ {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ ip, secret, response: token }),
+ },
+ );
+
+ const outcome = await response.json();
+ return outcome.success;
}
// Assume that this is a TypeScript route handler.
// You may replace this with a different implementation,
// based on your language or framework
export async function onRequestPost(context) {
- const { request, env } = context;
- const { username, password, token } = await request.json();
-
- // Validate Turnstile token
- const secretKey = env.TURNSTILE_SECRET_KEY;
- const ip = request.headers.get('CF-Connecting-IP');
- const turnstileValid = await validateTurnstileToken(ip, token, secretKey);
- if (!turnstileValid) {
- // Return back to the login page with an error message
- return Response.redirect('/login', 302, {
- headers: {
- 'Location': '/login?error=invalid-turnstile-token'
- }
- });
- }
-
- // Perform your existing authentication logic here
- const isValidLogin = await checkCredentials(username, password);
-
- if (isValidLogin) {
- return new Response(JSON.stringify({ message: 'Login successful' }), {
- status: 200,
- headers: { 'Content-Type': 'application/json' }
- });
- } else {
- return new Response(JSON.stringify({ error: 'Invalid credentials' }), {
- status: 401,
- headers: { 'Content-Type': 'application/json' }
- });
- }
+ const { request, env } = context;
+ const { username, password, token } = await request.json();
+
+ // Validate Turnstile token
+ const secretKey = env.TURNSTILE_SECRET_KEY;
+ const ip = request.headers.get("CF-Connecting-IP");
+ const turnstileValid = await validateTurnstileToken(ip, token, secretKey);
+ if (!turnstileValid) {
+ // Return back to the login page with an error message
+ return Response.redirect("/login", 302, {
+ headers: {
+ Location: "/login?error=invalid-turnstile-token",
+ },
+ });
+ }
+
+ // Perform your existing authentication logic here
+ const isValidLogin = await checkCredentials(username, password);
+
+ if (isValidLogin) {
+ return new Response(JSON.stringify({ message: "Login successful" }), {
+ status: 200,
+ headers: { "Content-Type": "application/json" },
+ });
+ } else {
+ return new Response(JSON.stringify({ error: "Invalid credentials" }), {
+ status: 401,
+ headers: { "Content-Type": "application/json" },
+ });
+ }
}
-async function checkCredentials(username: string, password: string): Promise {
- // Your existing credential checking logic
+async function checkCredentials(
+ username: string,
+ password: string,
+): Promise {
+ // Your existing credential checking logic
}
```
@@ -155,8 +164,8 @@ This setup ensures that the Turnstile token is validated on the server-side befo
After deployment, you will want to test your integration. Because your bot score will be low, you will probably not receive a challenge. However, you can add additional rules as needed to force a redirect to the challenge page. Some options to do this are:
-1) Add a WAF rule that always forwards your IP address to the challenge page.
-2) Add a WAF rule that checks for the presence of a query parameter, such as `?challenge=true`.
+1. Add a WAF rule that always forwards your IP address to the challenge page.
+2. Add a WAF rule that checks for the presence of a query parameter, such as `?challenge=true`.
## Best practices
@@ -172,4 +181,4 @@ If you are interested in customizing Turnstile, refer to the resources below for
- [Client-side rendering](/turnstile/get-started/client-side-rendering/). Learn how to customize how and when Turnstile renders in your user interface, to better fit your application's needs and user experience.
- [Server-side validation](/turnstile/get-started/server-side-validation/). Learn how Turnstile's API works, including request parameters, as well as how to handle different types of responses, including error codes.
-- [Turnstile Analytics](/turnstile/turnstile-analytics/). Learn how to view Turnstile's analytics in the Cloudflare dashboard. This includes metrics on the number of challenges issued, as well as the CSR (Challenge Solve Rate).
\ No newline at end of file
+- [Turnstile Analytics](/turnstile/turnstile-analytics/). Learn how to view Turnstile's analytics in the Cloudflare dashboard. This includes metrics on the number of challenges issued, as well as the CSR (Challenge Solve Rate).
diff --git a/src/content/docs/workflows/examples/backup-d1.mdx b/src/content/docs/workflows/examples/backup-d1.mdx
index 3bbcb77ecb3867..e128095dabf618 100644
--- a/src/content/docs/workflows/examples/backup-d1.mdx
+++ b/src/content/docs/workflows/examples/backup-d1.mdx
@@ -1,21 +1,20 @@
---
type: example
summary: Export a D1 database into R2 storage with Workflows
-tags:
+products:
- Workflows
- D1
- R2
languages:
- Typescript
-pcx_content_type: configuration
+pcx_content_type: example
title: Export and save D1 database
sidebar:
order: 3
description: Send invoice when shopping cart is checked out and paid for
-
---
-import { TabItem, Tabs, WranglerConfig } from "~/components"
+import { TabItem, Tabs, WranglerConfig } from "~/components";
In this example, we implement a Workflow periodically triggered by a [Cron Trigger](/workers/configuration/cron-triggers). That Workflow initiates a backup for a D1 database using the REST API, and then stores the SQL dump in an [R2](/r2) bucket.
@@ -33,79 +32,93 @@ This example provides simplified steps for backing up a [D1](/d1) database to he
```ts
import {
- WorkflowEntrypoint,
- WorkflowStep,
- WorkflowEvent,
+ WorkflowEntrypoint,
+ WorkflowStep,
+ WorkflowEvent,
} from "cloudflare:workers";
-
// We are using R2 to store the D1 backup
type Env = {
- BACKUP_WORKFLOW: Workflow;
- D1_REST_API_TOKEN: string;
- BACKUP_BUCKET: R2Bucket;
+ BACKUP_WORKFLOW: Workflow;
+ D1_REST_API_TOKEN: string;
+ BACKUP_BUCKET: R2Bucket;
};
// Workflow parameters: we expect accountId and databaseId
type Params = {
- accountId: string;
- databaseId: string;
+ accountId: string;
+ databaseId: string;
};
// Workflow logic
export class backupWorkflow extends WorkflowEntrypoint {
- async run(event: WorkflowEvent, step: WorkflowStep) {
- const { accountId, databaseId } = event.payload;
-
- const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/d1/database/${databaseId}/export`;
- const method = "POST";
- const headers = new Headers();
- headers.append("Content-Type", "application/json");
- headers.append("Authorization", `Bearer ${this.env.D1_REST_API_TOKEN}`);
-
- const bookmark = await step.do(`Starting backup for ${databaseId}`, async () => {
- const payload = { output_format: "polling" };
-
- const res = await fetch(url, { method, headers, body: JSON.stringify(payload) });
- const { result } = (await res.json()) as any;
-
- // If we don't get `at_bookmark` we throw to retry the step
- if (!result?.at_bookmark) throw new Error("Missing `at_bookmark`");
-
- return result.at_bookmark;
- });
-
- await step.do("Check backup status and store it on R2", async () => {
- const payload = { current_bookmark: bookmark };
-
- const res = await fetch(url, { method, headers, body: JSON.stringify(payload) });
- const { result } = (await res.json()) as any;
-
- // The endpoint sends `signed_url` when the backup is ready to download.
- // If we don't get `signed_url` we throw to retry the step.
- if (!result?.signed_url) throw new Error("Missing `signed_url`");
-
- const dumpResponse = await fetch(result.signed_url);
- if (!dumpResponse.ok) throw new Error("Failed to fetch dump file");
-
- // Finally, stream the file directly to R2
- await this.env.BACKUP_BUCKET.put(result.filename, dumpResponse.body);
- });
- }
+ async run(event: WorkflowEvent, step: WorkflowStep) {
+ const { accountId, databaseId } = event.payload;
+
+ const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/d1/database/${databaseId}/export`;
+ const method = "POST";
+ const headers = new Headers();
+ headers.append("Content-Type", "application/json");
+ headers.append("Authorization", `Bearer ${this.env.D1_REST_API_TOKEN}`);
+
+ const bookmark = await step.do(
+ `Starting backup for ${databaseId}`,
+ async () => {
+ const payload = { output_format: "polling" };
+
+ const res = await fetch(url, {
+ method,
+ headers,
+ body: JSON.stringify(payload),
+ });
+ const { result } = (await res.json()) as any;
+
+ // If we don't get `at_bookmark` we throw to retry the step
+ if (!result?.at_bookmark) throw new Error("Missing `at_bookmark`");
+
+ return result.at_bookmark;
+ },
+ );
+
+ await step.do("Check backup status and store it on R2", async () => {
+ const payload = { current_bookmark: bookmark };
+
+ const res = await fetch(url, {
+ method,
+ headers,
+ body: JSON.stringify(payload),
+ });
+ const { result } = (await res.json()) as any;
+
+ // The endpoint sends `signed_url` when the backup is ready to download.
+ // If we don't get `signed_url` we throw to retry the step.
+ if (!result?.signed_url) throw new Error("Missing `signed_url`");
+
+ const dumpResponse = await fetch(result.signed_url);
+ if (!dumpResponse.ok) throw new Error("Failed to fetch dump file");
+
+ // Finally, stream the file directly to R2
+ await this.env.BACKUP_BUCKET.put(result.filename, dumpResponse.body);
+ });
+ }
}
export default {
- async fetch(req: Request, env: Env): Promise {
- return new Response("Not found", { status: 404 });
- },
- async scheduled(controller: ScheduledController, env: Env, ctx: ExecutionContext) {
- const params: Params = {
- accountId: "{accountId}",
- databaseId: "{databaseId}",
- };
- const instance = await env.BACKUP_WORKFLOW.create({ params });
- console.log(`Started workflow: ${instance.id}`);
- },
+ async fetch(req: Request, env: Env): Promise {
+ return new Response("Not found", { status: 404 });
+ },
+ async scheduled(
+ controller: ScheduledController,
+ env: Env,
+ ctx: ExecutionContext,
+ ) {
+ const params: Params = {
+ accountId: "{accountId}",
+ databaseId: "{databaseId}",
+ };
+ const instance = await env.BACKUP_WORKFLOW.create({ params });
+ console.log(`Started workflow: ${instance.id}`);
+ },
};
```
@@ -113,10 +126,10 @@ Here is a minimal package.json:
```json
{
- "devDependencies": {
- "@cloudflare/workers-types": "^4.20241224.0",
- "wrangler": "^3.99.0"
- }
+ "devDependencies": {
+ "@cloudflare/workers-types": "^4.20241224.0",
+ "wrangler": "^3.99.0"
+ }
}
```
@@ -143,4 +156,4 @@ bucket_name = "d1-backups"
crons = [ "0 0 * * *" ]
```
-
\ No newline at end of file
+
diff --git a/src/content/docs/workflows/examples/index.mdx b/src/content/docs/workflows/examples/index.mdx
index 8765b2d0643a42..f958454afc9346 100644
--- a/src/content/docs/workflows/examples/index.mdx
+++ b/src/content/docs/workflows/examples/index.mdx
@@ -7,11 +7,10 @@ sidebar:
order: 6
group:
hideIndex: true
-
---
-import { GlossaryTooltip, ListExamples } from "~/components"
+import { GlossaryTooltip, ListExamples } from "~/components";
Explore the following examples for Workflows.
-
+
diff --git a/src/content/docs/workflows/examples/send-invoices.mdx b/src/content/docs/workflows/examples/send-invoices.mdx
index e3dfe27279f3f5..a746f2d49304ea 100644
--- a/src/content/docs/workflows/examples/send-invoices.mdx
+++ b/src/content/docs/workflows/examples/send-invoices.mdx
@@ -1,19 +1,18 @@
---
type: example
summary: Send invoice when shopping cart is checked out and paid for
-tags:
+products:
- Workflows
- D1
- Email Routing
-pcx_content_type: configuration
+pcx_content_type: example
title: Pay cart and send invoice
sidebar:
order: 3
description: Send invoice when shopping cart is checked out and paid for
-
---
-import { TabItem, Tabs, WranglerConfig } from "~/components"
+import { TabItem, Tabs, WranglerConfig } from "~/components";
In this example, we implement a Workflow for an e-commerce website that is triggered every time a shopping cart is created.
@@ -25,23 +24,23 @@ This is a simplified example of processing a shopping cart. We would assume more
```ts
import {
- WorkflowEntrypoint,
- WorkflowStep,
- WorkflowEvent,
+ WorkflowEntrypoint,
+ WorkflowStep,
+ WorkflowEvent,
} from "cloudflare:workers";
import { EmailMessage } from "cloudflare:email";
import { createMimeMessage } from "mimetext";
// We are using Email Routing to send emails out and D1 for our cart database
type Env = {
- CART_WORKFLOW: Workflow;
- SEND_EMAIL: any;
- DB: any;
+ CART_WORKFLOW: Workflow;
+ SEND_EMAIL: any;
+ DB: any;
};
// Workflow parameters: we expect a cartId
type Params = {
- cartId: string;
+ cartId: string;
};
// Adjust this to your Cloudflare zone using Email Routing
@@ -49,141 +48,140 @@ const merchantEmail = "merchant@example.com";
// Uses mimetext npm to generate Email
const genEmail = (email: string, amount: number) => {
- const msg = createMimeMessage();
- msg.setSender({ name: "Pet shop", addr: merchantEmail });
- msg.setRecipient(email);
- msg.setSubject("You invoice");
- msg.addMessage({
- contentType: "text/plain",
- data: `Your invoice for ${amount} has been paid. Your products will be shipped shortly.`,
- });
-
- return new EmailMessage(merchantEmail, email, msg.asRaw());
+ const msg = createMimeMessage();
+ msg.setSender({ name: "Pet shop", addr: merchantEmail });
+ msg.setRecipient(email);
+ msg.setSubject("You invoice");
+ msg.addMessage({
+ contentType: "text/plain",
+ data: `Your invoice for ${amount} has been paid. Your products will be shipped shortly.`,
+ });
+
+ return new EmailMessage(merchantEmail, email, msg.asRaw());
};
// Workflow logic
export class cartInvoicesWorkflow extends WorkflowEntrypoint {
- async run(event: WorkflowEvent, step: WorkflowStep) {
- await step.sleep("sleep for a while", "10 seconds");
-
- // Retrieve the cart from the D1 database
- // if the cart hasn't been checked out yet retry every 2 minutes, 10 times, otherwise give up
- const cart = await step.do(
- "retrieve cart",
- {
- retries: {
- limit: 10,
- delay: 2000 * 60,
- backoff: "constant",
- },
- timeout: "30 seconds",
- },
- async () => {
- const { results } = await this.env.DB.prepare(
- `SELECT * FROM cart WHERE id = ?`,
- )
- .bind(event.payload.cartId)
- .all();
- // should return { checkedOut: true, amount: 250 , account: { email: "celsomartinho@gmail.com" }};
- if(results[0].checkedOut === false) {
- throw new Error("cart hasn't been checked out yet");
- }
- return results[0];
- },
- );
-
- // Proceed to payment, retry 10 times every minute or give up
- const payment = await step.do(
- "payment",
- {
- retries: {
- limit: 10,
- delay: 1000 * 60,
- backoff: "constant",
- },
- timeout: "30 seconds",
- },
- async () => {
- let resp = await fetch("https://payment-processor.example.com/", {
- method: "POST",
- headers: {
- "Content-Type": "application/json; charset=utf-8",
- },
- body: JSON.stringify({ amount: cart.amount }),
- });
-
- if (!resp.ok) {
- throw new Error("payment has failed");
- }
-
- return { success: true, amount: cart.amount };
- },
- );
-
- // Send invoice to the customer, retry 10 times every 5 minutes or give up
+ async run(event: WorkflowEvent, step: WorkflowStep) {
+ await step.sleep("sleep for a while", "10 seconds");
+
+ // Retrieve the cart from the D1 database
+ // if the cart hasn't been checked out yet retry every 2 minutes, 10 times, otherwise give up
+ const cart = await step.do(
+ "retrieve cart",
+ {
+ retries: {
+ limit: 10,
+ delay: 2000 * 60,
+ backoff: "constant",
+ },
+ timeout: "30 seconds",
+ },
+ async () => {
+ const { results } = await this.env.DB.prepare(
+ `SELECT * FROM cart WHERE id = ?`,
+ )
+ .bind(event.payload.cartId)
+ .all();
+ // should return { checkedOut: true, amount: 250 , account: { email: "celsomartinho@gmail.com" }};
+ if (results[0].checkedOut === false) {
+ throw new Error("cart hasn't been checked out yet");
+ }
+ return results[0];
+ },
+ );
+
+ // Proceed to payment, retry 10 times every minute or give up
+ const payment = await step.do(
+ "payment",
+ {
+ retries: {
+ limit: 10,
+ delay: 1000 * 60,
+ backoff: "constant",
+ },
+ timeout: "30 seconds",
+ },
+ async () => {
+ let resp = await fetch("https://payment-processor.example.com/", {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json; charset=utf-8",
+ },
+ body: JSON.stringify({ amount: cart.amount }),
+ });
+
+ if (!resp.ok) {
+ throw new Error("payment has failed");
+ }
+
+ return { success: true, amount: cart.amount };
+ },
+ );
+
+ // Send invoice to the customer, retry 10 times every 5 minutes or give up
// Requires that cart.account.email has previously been validated in Email Routing,
// See https://developers.cloudflare.com/email-routing/email-workers/
- await step.do(
- "send invoice",
- {
- retries: {
- limit: 10,
- delay: 5000 * 60,
- backoff: "constant",
- },
- timeout: "30 seconds",
- },
- async () => {
- const message = genEmail(cart.account.email, payment.amount);
- try {
- await this.env.SEND_EMAIL.send(message);
- } catch (e) {
- throw new Error("failed to send invoice");
- }
- },
- );
-
- }
+ await step.do(
+ "send invoice",
+ {
+ retries: {
+ limit: 10,
+ delay: 5000 * 60,
+ backoff: "constant",
+ },
+ timeout: "30 seconds",
+ },
+ async () => {
+ const message = genEmail(cart.account.email, payment.amount);
+ try {
+ await this.env.SEND_EMAIL.send(message);
+ } catch (e) {
+ throw new Error("failed to send invoice");
+ }
+ },
+ );
+ }
}
// Default page for admin
// Remove in production
export default {
- async fetch(req: Request, env: Env): Promise {
- let url = new URL(req.url);
-
- let id = new URL(req.url).searchParams.get("instanceId");
-
- // Get the status of an existing instance, if provided
- if (id) {
- let instance = await env.CART_WORKFLOW.get(id);
- return Response.json({
- status: await instance.status(),
- });
- }
-
- if (url.pathname.startsWith("/new")) {
- let instance = await env.CART_WORKFLOW.create({
- params: {
- cartId: "123"
- },
- });
- return Response.json({
- id: instance.id,
- details: await instance.status(),
- });
- }
-
- return new Response(
- `new instance or add ?instanceId=...`,
- {
- headers: {
- "content-type": "text/html;charset=UTF-8",
- },
- },
- );
- },
+ async fetch(req: Request, env: Env): Promise {
+ let url = new URL(req.url);
+
+ let id = new URL(req.url).searchParams.get("instanceId");
+
+ // Get the status of an existing instance, if provided
+ if (id) {
+ let instance = await env.CART_WORKFLOW.get(id);
+ return Response.json({
+ status: await instance.status(),
+ });
+ }
+
+ if (url.pathname.startsWith("/new")) {
+ let instance = await env.CART_WORKFLOW.create({
+ params: {
+ cartId: "123",
+ },
+ });
+ return Response.json({
+ id: instance.id,
+ details: await instance.status(),
+ });
+ }
+
+ return new Response(
+ `new instance or add ?instanceId=...`,
+ {
+ headers: {
+ "content-type": "text/html;charset=UTF-8",
+ },
+ },
+ );
+ },
};
```
@@ -191,13 +189,13 @@ Here's a minimal package.json:
```json
{
- "devDependencies": {
- "@cloudflare/workers-types": "^4.20241022.0",
- "wrangler": "^3.83.0"
- },
- "dependencies": {
- "mimetext": "^3.0.24"
- }
+ "devDependencies": {
+ "@cloudflare/workers-types": "^4.20241022.0",
+ "wrangler": "^3.83.0"
+ },
+ "dependencies": {
+ "mimetext": "^3.0.24"
+ }
}
```
@@ -220,4 +218,4 @@ class_name = "cartInvoicesWorkflow"
name = "SEND_EMAIL"
```
-
\ No newline at end of file
+
diff --git a/src/content/docs/workflows/examples/twilio.mdx b/src/content/docs/workflows/examples/twilio.mdx
index c6eafab8d2ac25..f42e993bb15e57 100644
--- a/src/content/docs/workflows/examples/twilio.mdx
+++ b/src/content/docs/workflows/examples/twilio.mdx
@@ -1,22 +1,21 @@
---
type: example
summary: Integrate Workflows with Twilio. Learn how to receive and send text messages and phone calls via APIs and Webhooks.
-tags:
- - Workflows
+products:
- Workers
-pcx_content_type: configuration
+pcx_content_type: example
title: Integrate Workflows with Twilio
sidebar:
order: 4
description: Integrate Workflows with Twilio. Learn how to receive and send text messages and phone calls via APIs and Webhooks.
---
-import { Stream } from "~/components"
+import { Stream } from "~/components";
Using the following [repository](https://github.com/craigsdennis/twilio-cloudflare-workflow), learn how to integrate Cloudflare Workflows with Twilio, a popular cloud communications platform that enables developers to integrate messaging, voice, video, and authentication features into applications via APIs. By the end of the video tutorial, you will become familiarized with the process of setting up Cloudflare Workflows to seamlessly interact with Twilio's APIs, enabling you to build interesting communication features directly into your applications.
-
-
-
-
-
+