diff --git a/src/content/docs/workers/examples/alter-headers.mdx b/src/content/docs/workers/examples/alter-headers.mdx index f04da40ccc49445..33ed6af55674e80 100644 --- a/src/content/docs/workers/examples/alter-headers.mdx +++ b/src/content/docs/workers/examples/alter-headers.mdx @@ -90,7 +90,7 @@ async def on_fetch(request): # Add a custom header with a value new_headers["x-workers-hello"] = "Hello from Cloudflare Workers" - + # Delete headers if "x-header-to-delete" in new_headers: del new_headers["x-header-to-delete"] @@ -113,19 +113,19 @@ const app = new Hono(); app.use('*', async (c, next) => { // Process the request with the next middleware/handler await next(); - + // After the response is generated, we can modify its headers - + // Add a custom header with a value c.res.headers.append( "x-workers-hello", "Hello from Cloudflare Workers with Hono" ); - + // Delete headers c.res.headers.delete("x-header-to-delete"); c.res.headers.delete("x-header2-to-delete"); - + // Adjust the value for an existing header c.res.headers.set("x-header-to-change", "NewValue"); }); @@ -133,7 +133,7 @@ app.use('*', async (c, next) => { app.get('*', async (c) => { // Fetch content from example.com const response = await fetch("https://example.com"); - + // Return the response body with original headers // (our middleware will modify the headers before sending) return new Response(response.body, { diff --git a/src/content/docs/workers/examples/auth-with-headers.mdx b/src/content/docs/workers/examples/auth-with-headers.mdx index 121f1ff57f84681..f028f87a0822cd3 100644 --- a/src/content/docs/workers/examples/auth-with-headers.mdx +++ b/src/content/docs/workers/examples/auth-with-headers.mdx @@ -109,7 +109,7 @@ app.use('*', async (c, next) => { */ const PRESHARED_AUTH_HEADER_KEY = "X-Custom-PSK"; const PRESHARED_AUTH_HEADER_VALUE = "mypresharedkey"; - + // Get the pre-shared key from the request header const psk = c.req.header(PRESHARED_AUTH_HEADER_KEY); diff --git a/src/content/docs/workers/examples/cache-using-fetch.mdx b/src/content/docs/workers/examples/cache-using-fetch.mdx index e42e86d9106b6d6..e8cafe90e2ae0ff 100644 --- a/src/content/docs/workers/examples/cache-using-fetch.mdx +++ b/src/content/docs/workers/examples/cache-using-fetch.mdx @@ -87,11 +87,11 @@ const app = new Hono<{ Bindings: Bindings }>(); app.all('*', async (c) => { const url = new URL(c.req.url); - + // Only use the path for the cache key, removing query strings // and always store using HTTPS, for example, https://www.example.com/file-uri-here const someCustomKey = `https://${url.hostname}${url.pathname}`; - + // Fetch the request with custom cache settings let response = await fetch(c.req.raw, { cf: { @@ -103,13 +103,13 @@ app.all('*', async (c) => { cacheKey: someCustomKey, }, }); - + // Reconstruct the Response object to make its headers mutable response = new Response(response.body, response); - + // Set cache control headers to cache on browser for 25 minutes response.headers.set("Cache-Control", "max-age=1500"); - + return response; }); @@ -278,17 +278,17 @@ const app = new Hono<{ Bindings: Bindings }>(); app.all('*', async (c) => { const originalUrl = c.req.url; const url = new URL(originalUrl); - + // Randomly select a storage backend if (Math.random() < 0.5) { url.hostname = "example.s3.amazonaws.com"; } else { url.hostname = "example.storage.googleapis.com"; } - + // Create a new request to the selected backend const newRequest = new Request(url, c.req.raw); - + // Fetch using the original URL as the cache key return fetch(newRequest, { cf: { cacheKey: originalUrl }, diff --git a/src/content/docs/workers/examples/country-code-redirect.mdx b/src/content/docs/workers/examples/country-code-redirect.mdx index fe6b7da2794c8f3..aab79a55ab121cb 100644 --- a/src/content/docs/workers/examples/country-code-redirect.mdx +++ b/src/content/docs/workers/examples/country-code-redirect.mdx @@ -127,7 +127,7 @@ app.get('*', async (c) => { // Cast the raw request to include Cloudflare-specific properties const request = c.req.raw as RequestWithCf; - + // Use the cf object to obtain the country of the request // more on the cf object: https://developers.cloudflare.com/workers/runtime-apis/request#incomingrequestcfproperties const country = request.cf.country; diff --git a/src/content/docs/workers/examples/cron-trigger.mdx b/src/content/docs/workers/examples/cron-trigger.mdx index 99084729e2d0355..3efa2e87c154bf7 100644 --- a/src/content/docs/workers/examples/cron-trigger.mdx +++ b/src/content/docs/workers/examples/cron-trigger.mdx @@ -49,7 +49,7 @@ app.get('/', (c) => c.text('Hello World!')); export default { // The Hono app handles regular HTTP requests fetch: app.fetch, - + // The scheduled function handles Cron triggers async scheduled( controller: ScheduledController, @@ -57,7 +57,7 @@ export default { ctx: ExecutionContext, ) { console.log("cron processed"); - + // You could also perform actions like: // - Fetching data from external APIs // - Updating KV or Durable Object storage diff --git a/src/content/docs/workers/examples/data-loss-prevention.mdx b/src/content/docs/workers/examples/data-loss-prevention.mdx index e7d6a3e1ac9e65d..c64c08aafd031d5 100644 --- a/src/content/docs/workers/examples/data-loss-prevention.mdx +++ b/src/content/docs/workers/examples/data-loss-prevention.mdx @@ -258,30 +258,30 @@ async function postDataBreach(request: Request) { app.use('*', async (c) => { // Fetch the origin response const response = await fetch(c.req.raw); - + // Return origin response if response wasn't text const contentType = response.headers.get("content-type") || ""; if (!contentType.toLowerCase().includes("text/")) { return response; } - + // Get the response text let text = await response.text(); - + // When debugging, replace the response from the origin with an email text = DEBUG ? text.replace("You may use this", "me@example.com may use this") : text; - + // Check for sensitive data for (const kind in sensitiveRegexsMap) { const sensitiveRegex = new RegExp(sensitiveRegexsMap[kind], "ig"); const match = sensitiveRegex.test(text); - + if (match) { // Alert a data breach await postDataBreach(c.req.raw); - + // Respond with a block if credit card, otherwise replace sensitive text with `*`s if (kind === "creditCard") { return c.text(`${kind} found\nForbidden\n`, 403); @@ -294,7 +294,7 @@ app.use('*', async (c) => { } } } - + // Return the modified response return new Response(text, { status: response.status, diff --git a/src/content/docs/workers/examples/debugging-logs.mdx b/src/content/docs/workers/examples/debugging-logs.mdx index d706124f7ba1225..234fe35cfac1c6f 100644 --- a/src/content/docs/workers/examples/debugging-logs.mdx +++ b/src/content/docs/workers/examples/debugging-logs.mdx @@ -168,7 +168,7 @@ app.use('*', async (c, next) => { try { // Process the request with the next handler await next(); - + // After processing, check if the response indicates an error if (c.res && (!c.res.ok && !c.res.redirected)) { const body = await c.res.clone().text(); @@ -180,28 +180,28 @@ app.use('*', async (c, next) => { body.trim().substring(0, 10) ); } - + } catch (err) { // Without waitUntil, the fetch to the logging service may not complete c.executionCtx.waitUntil( postLog(err.toString()) ); - + // Get the error stack or error itself const stack = JSON.stringify(err.stack) || err.toString(); - + // Create a new response with the error information - const response = c.res ? + const response = c.res ? new Response(stack, { status: c.res.status, headers: c.res.headers - }) : + }) : new Response(stack, { status: 500 }); - + // Add debug headers response.headers.set("X-Debug-stack", stack); response.headers.set("X-Debug-err", err.toString()); - + // Set the modified response c.res = response; } diff --git a/src/content/docs/workers/examples/extract-cookie-value.mdx b/src/content/docs/workers/examples/extract-cookie-value.mdx index e7ca1c827b34c34..435761c5d22eccc 100644 --- a/src/content/docs/workers/examples/extract-cookie-value.mdx +++ b/src/content/docs/workers/examples/extract-cookie-value.mdx @@ -84,15 +84,15 @@ const app = new Hono(); app.get('*', (c) => { // The name of the cookie const COOKIE_NAME = "__uid"; - + // Get the specific cookie value using Hono's cookie helper const cookieValue = getCookie(c, COOKIE_NAME); - + if (cookieValue) { // Respond with the cookie value return c.text(cookieValue); } - + return c.text("No cookie with name: " + COOKIE_NAME); }); diff --git a/src/content/docs/workers/examples/fetch-json.mdx b/src/content/docs/workers/examples/fetch-json.mdx index fbfdd541d4f5e22..4f7f9d64bbffd3c 100644 --- a/src/content/docs/workers/examples/fetch-json.mdx +++ b/src/content/docs/workers/examples/fetch-json.mdx @@ -113,11 +113,11 @@ app.get('*', async (c) => { async function gatherResponse(response: Response) { const { headers } = response; const contentType = headers.get("content-type") || ""; - + if (contentType.includes("application/json")) { return { contentType, result: JSON.stringify(await response.json()) }; } - + return { contentType, result: await response.text() }; } diff --git a/src/content/docs/workers/examples/geolocation-app-weather.mdx b/src/content/docs/workers/examples/geolocation-app-weather.mdx index ef190d1c3f5b68c..d752396fc245c89 100644 --- a/src/content/docs/workers/examples/geolocation-app-weather.mdx +++ b/src/content/docs/workers/examples/geolocation-app-weather.mdx @@ -149,18 +149,18 @@ app.get('*', async (c) => { // Get API endpoint let endpoint = "https://api.waqi.info/feed/geo:"; const token = ""; // Use a token from https://aqicn.org/api/ - + // Define styles const html_style = `body{padding:6em; font-family: sans-serif;} h1{color:#f6821f}`; - + // Get geolocation from Cloudflare request const req = c.req.raw; const latitude = req.cf?.latitude; const longitude = req.cf?.longitude; - + // Create complete API endpoint with coordinates endpoint += `${latitude};${longitude}/?token=${token}`; - + // Fetch weather data const init = { headers: { @@ -169,7 +169,7 @@ app.get('*', async (c) => { }; const response = await fetch(endpoint, init); const content = await response.json() as WeatherApiResponse; - + // Build HTML content const weatherContent = html`

Weather 🌦

@@ -181,7 +181,7 @@ app.get('*', async (c) => {

The O3 level is: ${content.data.iaqi.o3?.v}.

The temperature is: ${content.data.iaqi.t?.v}°C.

`; - + // Complete HTML document const htmlDocument = html` @@ -195,7 +195,7 @@ app.get('*', async (c) => { `; - + // Return HTML response return c.html(htmlDocument); }); diff --git a/src/content/docs/workers/examples/geolocation-custom-styling.mdx b/src/content/docs/workers/examples/geolocation-custom-styling.mdx index 416cd92c9f41102..c6e019dfd3e0930 100644 --- a/src/content/docs/workers/examples/geolocation-custom-styling.mdx +++ b/src/content/docs/workers/examples/geolocation-custom-styling.mdx @@ -485,19 +485,19 @@ async function toCSSGradient(hour: number): Promise { let css = "linear-gradient(to bottom,"; const data = grads[hour]; const len = data.length; - + for (let i = 0; i < len; i++) { const item = data[i]; css += ` #${item.color} ${item.position}%`; if (i < len - 1) css += ","; } - + return css + ")"; } app.get('*', async (c) => { const request = c.req.raw; - + // Base HTML style let html_style = ` html{width:100vw; height:100vh;} @@ -511,26 +511,26 @@ app.get('*', async (c) => { color:white; font-family:sans-serif; }`; - + // Get timezone from Cloudflare request const timezone = request.cf?.timezone || 'UTC'; console.log(timezone); - + // Get localized time let localized_date = new Date( new Date().toLocaleString("en-US", { timeZone: timezone }) ); - + let hour = localized_date.getHours(); let minutes = localized_date.getMinutes(); - + // Generate HTML content let html_content = `

${hour}:${minutes}

`; html_content += `

${timezone}

`; - + // Add background gradient based on hour html_style += `body{background:${await toCSSGradient(hour)};}`; - + // Complete HTML document let html = ` @@ -543,7 +543,7 @@ app.get('*', async (c) => { ${html_content} `; - + return c.html(html); }); diff --git a/src/content/docs/workers/examples/images-workers.mdx b/src/content/docs/workers/examples/images-workers.mdx index 776068d2a938b98..cd59070c01e21e8 100644 --- a/src/content/docs/workers/examples/images-workers.mdx +++ b/src/content/docs/workers/examples/images-workers.mdx @@ -75,12 +75,12 @@ app.get('*', async (c) => { // You can find this in the dashboard, it should look something like this: ZWd9g1K7eljCn_KDTu_MWA // Either get it from environment or hardcode it here const accountHash = c.env.ACCOUNT_HASH || ""; - + const url = new URL(c.req.url); - + // A request to something like cdn.example.com/83eb7b2-5392-4565-b69e-aff66acddd00/public // will fetch "https://imagedelivery.net//83eb7b2-5392-4565-b69e-aff66acddd00/public" - + return fetch(`https://imagedelivery.net/${accountHash}${url.pathname}`); }); diff --git a/src/content/docs/workers/examples/modify-response.mdx b/src/content/docs/workers/examples/modify-response.mdx index 5ecc7de99f8021f..40cd85256300ac6 100644 --- a/src/content/docs/workers/examples/modify-response.mdx +++ b/src/content/docs/workers/examples/modify-response.mdx @@ -175,11 +175,11 @@ app.get('*', async (c) => { // Get the JSON body from the original response const originalBody = await originalResponse.json(); - + // Modify the body by adding a new property - const modifiedBody = { - foo: "bar", - ...originalBody + const modifiedBody = { + foo: "bar", + ...originalBody }; // Create a new custom response with modified status, headers, and body diff --git a/src/content/docs/workers/examples/post-json.mdx b/src/content/docs/workers/examples/post-json.mdx index f088344d09b1e4f..7df950c2f509ca5 100644 --- a/src/content/docs/workers/examples/post-json.mdx +++ b/src/content/docs/workers/examples/post-json.mdx @@ -190,7 +190,7 @@ app.get('*', async (c) => { async function gatherResponse(response: Response) { const { headers } = response; const contentType = headers.get("content-type") || ""; - + if (contentType.includes("application/json")) { return { contentType, result: JSON.stringify(await response.json()) }; } else if (contentType.includes("application/text")) { @@ -209,10 +209,10 @@ app.get('*', async (c) => { "content-type": "application/json;charset=UTF-8", }, }; - + const response = await fetch(url, init); const { contentType, result } = await gatherResponse(response); - + return new Response(result, { headers: { "content-type": contentType, diff --git a/src/content/docs/workers/examples/protect-against-timing-attacks.mdx b/src/content/docs/workers/examples/protect-against-timing-attacks.mdx index 805f7240327472e..29c90441b3a8257 100644 --- a/src/content/docs/workers/examples/protect-against-timing-attacks.mdx +++ b/src/content/docs/workers/examples/protect-against-timing-attacks.mdx @@ -110,32 +110,32 @@ const app = new Hono(); // Middleware to handle authentication with timing-safe comparison app.use('*', async (c, next) => { const secret = c.env.MY_SECRET_VALUE; - + if (!secret) { return c.text("Missing secret binding", 500); } - + const authToken = c.req.header("Authorization") || ""; - + // Early length check to avoid unnecessary processing if (authToken.length !== secret.length) { return c.text("Unauthorized", 401); } - + const encoder = new TextEncoder(); - + const a = encoder.encode(authToken); const b = encoder.encode(secret); - + if (a.byteLength !== b.byteLength) { return c.text("Unauthorized", 401); } - + // Perform timing-safe comparison if (!crypto.subtle.timingSafeEqual(a, b)) { return c.text("Unauthorized", 401); } - + // If we got here, the auth token is valid await next(); }); diff --git a/src/content/docs/workers/examples/redirect.mdx b/src/content/docs/workers/examples/redirect.mdx index d217581ccc2243f..ab268cfe4d546eb 100644 --- a/src/content/docs/workers/examples/redirect.mdx +++ b/src/content/docs/workers/examples/redirect.mdx @@ -175,10 +175,10 @@ app.all('*', (c) => { const statusCode = 301; const { pathname, search } = new URL(c.req.url); - + const destinationURL = `${base}${pathname}${search}`; console.log(destinationURL); - + return c.redirect(destinationURL, statusCode); }); diff --git a/src/content/docs/workers/examples/rewrite-links.mdx b/src/content/docs/workers/examples/rewrite-links.mdx index ceccb897d533a2d..2d97f205b3ff4e8 100644 --- a/src/content/docs/workers/examples/rewrite-links.mdx +++ b/src/content/docs/workers/examples/rewrite-links.mdx @@ -143,11 +143,11 @@ app.get('*', async (c) => { class AttributeRewriter { attributeName: string; - + constructor(attributeName: string) { this.attributeName = attributeName; } - + element(element: Element) { const attribute = element.getAttribute(this.attributeName); if (attribute) { @@ -168,7 +168,7 @@ app.get('*', async (c) => { const rewriter = new HTMLRewriter() .on("a", new AttributeRewriter("href")) .on("img", new AttributeRewriter("src")); - + return new Response(rewriter.transform(res).body, { headers: res.headers }); diff --git a/src/content/docs/workers/get-started/dashboard.mdx b/src/content/docs/workers/get-started/dashboard.mdx index 7f8fcaa1ab4e407..d1f6c182bb6577e 100644 --- a/src/content/docs/workers/get-started/dashboard.mdx +++ b/src/content/docs/workers/get-started/dashboard.mdx @@ -24,35 +24,35 @@ To get started with a new Workers application: 1. Log in to the [Cloudflare dashboard](https://dash.cloudflare.com) and select your account. 2. Go to the **Workers & Pages** section of the dashboard. -2. Select [Create](https://dash.cloudflare.com/?to=/:account/workers-and-pages/create). From here, you can: +2. Select [Create](https://dash.cloudflare.com/?to=/:account/workers-and-pages/create). From here, you can: * You can select from the gallery of production-ready templates * Import an existing Git repository on your own account - * Let Cloudflare clone and bootstrap a public repository containing a Workers application. -3. Once you've connected to your chosen [Git provider](/workers/ci-cd/builds/git-integration/github-integration/), configure your project and click `Deploy`. -4. Cloudflare will kick off a new build and deployment. Once deployed, preview your Worker at its provided `workers.dev` subdomain. + * Let Cloudflare clone and bootstrap a public repository containing a Workers application. +3. Once you've connected to your chosen [Git provider](/workers/ci-cd/builds/git-integration/github-integration/), configure your project and click `Deploy`. +4. Cloudflare will kick off a new build and deployment. Once deployed, preview your Worker at its provided `workers.dev` subdomain. ## Continue development -Applications started in the dashboard are set up with Git to help kickstart your development workflow. To continue developing on your repository, you can run: +Applications started in the dashboard are set up with Git to help kickstart your development workflow. To continue developing on your repository, you can run: ```bash # clone you repository locally git clone -# be sure you are in the root directory +# be sure you are in the root directory cd ``` -Now, you can preview and test your changes by [running Wrangler in your local development environment](/workers/local-development/). Once you are ready to deploy you can run: +Now, you can preview and test your changes by [running Wrangler in your local development environment](/workers/local-development/). Once you are ready to deploy you can run: ```bash # adds the files to git tracking -git add . +git add . -# commits the changes +# commits the changes git commit -m "your message" -# push the changes to your Git provider -git push origin main +# push the changes to your Git provider +git push origin main ``` diff --git a/src/content/docs/workers/get-started/prompting.mdx b/src/content/docs/workers/get-started/prompting.mdx index 0dabe98341a4a55..ea0310957381cb5 100644 --- a/src/content/docs/workers/get-started/prompting.mdx +++ b/src/content/docs/workers/get-started/prompting.mdx @@ -117,7 +117,7 @@ export default { ## Use docs in your editor -AI-enabled editors, including Cursor and Windsurf, can index documentation. Cursor includes the Cloudflare Developer Docs by default: you can use the [`@Docs`](https://docs.cursor.com/context/@-symbols/@-docs) command. +AI-enabled editors, including Cursor and Windsurf, can index documentation. Cursor includes the Cloudflare Developer Docs by default: you can use the [`@Docs`](https://docs.cursor.com/context/@-symbols/@-docs) command. In other editors, such as Zed or Windsurf, you can paste in URLs to add to your context. Use the _Copy Page_ button to paste in Cloudflare docs directly, or fetch docs for each product by appending `llms-full.txt` to the root URL - for example, `https://developers.cloudflare.com/agents/llms-full.txt` or `https://developers.cloudflare.com/workflows/llms-full.txt`. diff --git a/src/content/docs/workers/languages/typescript/index.mdx b/src/content/docs/workers/languages/typescript/index.mdx index 2bf5240648ada82..cd38b72d462cc28 100644 --- a/src/content/docs/workers/languages/typescript/index.mdx +++ b/src/content/docs/workers/languages/typescript/index.mdx @@ -58,7 +58,7 @@ To ensure that your types are always up-to-date, make sure to run `wrangler type Migrating from `@cloudflare/workers-types` to `wrangler types` -We recommend you use `wrangler types` to generate runtime types, rather than using the `@cloudflare/workers-types` package, as it generates types based on your Worker's [compatibility date](https://github.com/cloudflare/workerd/tree/main/npm/workers-types#compatibility-dates) and `compatibility flags`, ensuring that types match the exact runtime APIs made available to your Worker. +We recommend you use `wrangler types` to generate runtime types, rather than using the `@cloudflare/workers-types` package, as it generates types based on your Worker's [compatibility date](https://github.com/cloudflare/workerd/tree/main/npm/workers-types#compatibility-dates) and `compatibility flags`, ensuring that types match the exact runtime APIs made available to your Worker. :::note diff --git a/src/content/docs/workers/platform/deploy-buttons.mdx b/src/content/docs/workers/platform/deploy-buttons.mdx index b9ab65e9a050991..ca8c5d29918ee95 100644 --- a/src/content/docs/workers/platform/deploy-buttons.mdx +++ b/src/content/docs/workers/platform/deploy-buttons.mdx @@ -9,67 +9,67 @@ description: Set up a Deploy to Cloudflare button import { Tabs, TabItem } from "@astrojs/starlight/components"; -If you're building a Workers application and would like to share it with other developers, you can embed a Deploy to Cloudflare button in your README, blog post, or documentation to enable others to quickly deploy your application on their own Cloudflare account. Deploy to Cloudflare buttons eliminate the need for complex setup, allowing developers to get started with your public GitHub or GitLab repository in just a few clicks. +If you're building a Workers application and would like to share it with other developers, you can embed a Deploy to Cloudflare button in your README, blog post, or documentation to enable others to quickly deploy your application on their own Cloudflare account. Deploy to Cloudflare buttons eliminate the need for complex setup, allowing developers to get started with your public GitHub or GitLab repository in just a few clicks. [![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/cloudflare/templates/tree/staging/saas-admin-template) -## What are Deploy to Cloudflare buttons? +## What are Deploy to Cloudflare buttons? Deploy to Cloudflare buttons simplify the deployment of a Workers application by enabling Cloudflare to: -* **Clone a Git repository**: Cloudflare clones your source repository into the user's GitHub/GitLab account where they can continue development after deploying. -* **Configure a project**: Your users can customize key details such as repository name, Worker name, and required resource names in a single setup page with customizations reflected in the newly created Git repository. +* **Clone a Git repository**: Cloudflare clones your source repository into the user's GitHub/GitLab account where they can continue development after deploying. +* **Configure a project**: Your users can customize key details such as repository name, Worker name, and required resource names in a single setup page with customizations reflected in the newly created Git repository. * **Build & deploy**: Cloudflare builds the application using [Workers Builds](/workers/ci-cd/builds) and deploys it to the Cloudflare network. Any required resources are automatically provisioned and bound to the Worker without additional setup. ![Deploy to Cloudflare Flow](~/assets/images/workers/dtw-user-flow.png) -## How to Set Up Deploy to Cloudflare buttons -Deploy to Cloudflare buttons can be embedded anywhere developers might want to launch your project. To add a Deploy to Cloudflare button, copy the following snippet and replace the Git repository URL with your project's URL. You can also optionally specify a subdirectory. +## How to Set Up Deploy to Cloudflare buttons +Deploy to Cloudflare buttons can be embedded anywhere developers might want to launch your project. To add a Deploy to Cloudflare button, copy the following snippet and replace the Git repository URL with your project's URL. You can also optionally specify a subdirectory. - + ```md [![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=) ``` - + ```html Deploy to Cloudflare ``` - + ``` https://deploy.workers.cloudflare.com/?url= ``` - + -If you have already deployed your application using Workers Builds, you can generate a Deploy to Cloudflare button directly from the Cloudflare dashboard by selecting the share button (located within your Worker details) and copying the provided snippet. +If you have already deployed your application using Workers Builds, you can generate a Deploy to Cloudflare button directly from the Cloudflare dashboard by selecting the share button (located within your Worker details) and copying the provided snippet. ![Share an application](~/assets/images/workers/dtw-share-project.png) -Once you have your snippet, you can paste this wherever you would like your button to be displayed. +Once you have your snippet, you can paste this wherever you would like your button to be displayed. -## Automatic Resource provisioning +## Automatic Resource provisioning If your Worker application requires Cloudflare resources, they will be automatically provisioned as part of the deployment. Currently, supported resources include: * **Storage**: [KV namespaces](/kv/), [D1 databases](/d1/), [R2 buckets](/r2/), [Hyperdrive](/hyperdrive/), and [Vectorize databases](/vectorize/) * **Compute**: [Durable Objects](/durable-objects/), [Workers AI](/workers-ai/), and [Queues](/queues/) -Cloudflare will read the Wrangler configuration file of your source repo to determine resource requirements for your application. During deployment, Cloudflare will provision any necessary resources and update the Wrangler configuration where applicable for newly created resources (e.g. database IDs and namespace IDs). To ensure successful deployment, please make sure your source repository includes default values for resource names, resource IDs and any other properties for each binding. +Cloudflare will read the Wrangler configuration file of your source repo to determine resource requirements for your application. During deployment, Cloudflare will provision any necessary resources and update the Wrangler configuration where applicable for newly created resources (e.g. database IDs and namespace IDs). To ensure successful deployment, please make sure your source repository includes default values for resource names, resource IDs and any other properties for each binding. -## Best practices -**Configuring Build/Deploy commands**: If you are using custom `build` and `deploy` scripts in your package.json (for example, if using a full stack framework or running D1 migrations), Cloudfare will automatically detect and pre-populate the build and deploy fields. Users can choose to modify or accept the custom commands during deployment configuration. +## Best practices +**Configuring Build/Deploy commands**: If you are using custom `build` and `deploy` scripts in your package.json (for example, if using a full stack framework or running D1 migrations), Cloudfare will automatically detect and pre-populate the build and deploy fields. Users can choose to modify or accept the custom commands during deployment configuration. -If no `deploy` script is specified, Cloudflare will preconfigure `npx wrangler deploy` by default. If no `build` script is specified, Cloudflare will leave this field blank. +If no `deploy` script is specified, Cloudflare will preconfigure `npx wrangler deploy` by default. If no `build` script is specified, Cloudflare will leave this field blank. **Running D1 Migrations**: If you would like to run migrations as part of your setup, you can specify this in your `package.json` by running your migrations as part of your `deploy` script. The migration command should reference the binding name rather than the database name to ensure migrations are successful when users specify a database name that is different from that of your source repository. The following is an example of how you can set up the scripts section of your `package.json`: ```json { "scripts": { - "build": "astro build", + "build": "astro build", "deploy": "npm run db:migrations:apply && wrangler deploy", "db:migrations:apply": "wrangler d1 migrations apply DB_BINDING --remote" } @@ -79,8 +79,8 @@ If no `deploy` script is specified, Cloudflare will preconfigure `npx wrangler d ## Limitations * **Monorepos**: Cloudflare does not fully support monorepos - * If your repository URL contains a subdirectory, your application must be fully isolated within that subdirectory, including any dependencies. Otherwise, the build will fail. Cloudflare treats this subdirectory as the root of the new repository created as part of the deploy process. + * If your repository URL contains a subdirectory, your application must be fully isolated within that subdirectory, including any dependencies. Otherwise, the build will fail. Cloudflare treats this subdirectory as the root of the new repository created as part of the deploy process. * Additionally, if you have a monorepo that contains multiple Workers applications, they will not be deployed together. You must configure a separate Deploy to Cloudflare button for each application. The user will manually create a distinct Workers application for each subdirectory. * **Pages applications**: Deploy to Cloudflare buttons only support Workers applications. -* **Non-GitHub/GitLab repositories**: Source repositories from anything other than github.com and gitlab.com are not supported. Self-hosted versions of GitHub and GitLab are also not supported. +* **Non-GitHub/GitLab repositories**: Source repositories from anything other than github.com and gitlab.com are not supported. Self-hosted versions of GitHub and GitLab are also not supported. * **Private repositories**: Repositories must be public in order for others to successfully use your Deploy to Cloudflare button. \ No newline at end of file diff --git a/src/content/docs/workers/testing/vitest-integration/known-issues.mdx b/src/content/docs/workers/testing/vitest-integration/known-issues.mdx index 50c702138d3e3db..7c6e47a65e0f3e4 100644 --- a/src/content/docs/workers/testing/vitest-integration/known-issues.mdx +++ b/src/content/docs/workers/testing/vitest-integration/known-issues.mdx @@ -58,7 +58,7 @@ using result = await stub.getCounter(); When making requests via `fetch` or `R2.get()`, consume the entire response body, even if you are not asserting its content. For example: -```ts +```ts test('check if file exists', async () => { await env.R2.put('file', 'hello-world'); const response = await env.R2.get('file'); diff --git a/src/content/docs/workers/wrangler/install-and-update.mdx b/src/content/docs/workers/wrangler/install-and-update.mdx index 5c17966976e8f15..46461d4eb673eb0 100644 --- a/src/content/docs/workers/wrangler/install-and-update.mdx +++ b/src/content/docs/workers/wrangler/install-and-update.mdx @@ -14,7 +14,7 @@ Wrangler is a command-line tool for building with Cloudflare developer products. ## Install Wrangler -To install [Wrangler](https://github.com/cloudflare/workers-sdk/tree/main/packages/wrangler), ensure you have [Node.js](https://nodejs.org/en/) and [npm](https://docs.npmjs.com/getting-started) installed, preferably using a Node version manager like [Volta](https://volta.sh/) or [nvm](https://github.com/nvm-sh/nvm). Using a version manager helps avoid permission issues and allows you to change Node.js versions. +To install [Wrangler](https://github.com/cloudflare/workers-sdk/tree/main/packages/wrangler), ensure you have [Node.js](https://nodejs.org/en/) and [npm](https://docs.npmjs.com/getting-started) installed, preferably using a Node version manager like [Volta](https://volta.sh/) or [nvm](https://github.com/nvm-sh/nvm). Using a version manager helps avoid permission issues and allows you to change Node.js versions.
Wrangler System Requirements