diff --git a/patches/@astrojs+starlight+0.29.3.patch b/patches/@astrojs+starlight+0.29.3.patch
new file mode 100644
index 00000000000000..50cfcfdd1c967e
--- /dev/null
+++ b/patches/@astrojs+starlight+0.29.3.patch
@@ -0,0 +1,26 @@
+diff --git a/node_modules/@astrojs/starlight/user-components/Tabs.astro b/node_modules/@astrojs/starlight/user-components/Tabs.astro
+index 4234eb0..276d211 100644
+--- a/node_modules/@astrojs/starlight/user-components/Tabs.astro
++++ b/node_modules/@astrojs/starlight/user-components/Tabs.astro
+@@ -3,10 +3,11 @@ import Icon from './Icon.astro';
+ import { processPanels } from './rehype-tabs';
+
+ interface Props {
++ IconComponent?: typeof Icon;
+ syncKey?: string;
+ }
+
+-const { syncKey } = Astro.props;
++const { syncKey, IconComponent = Icon } = Astro.props;
+ const panelHtml = await Astro.slots.render('default');
+ const { html, panels } = processPanels(panelHtml);
+
+@@ -84,7 +85,7 @@ if (isSynced) {
+ aria-selected={idx === 0 ? 'true' : 'false'}
+ tabindex={idx !== 0 ? -1 : 0}
+ >
+- {icon && }
++ {icon && }
+ {label}
+
+
diff --git a/src/content/docs/cloudflare-for-platforms/workers-for-platforms/configuration/static-assets.mdx b/src/content/docs/cloudflare-for-platforms/workers-for-platforms/configuration/static-assets.mdx
new file mode 100644
index 00000000000000..360660fabd6183
--- /dev/null
+++ b/src/content/docs/cloudflare-for-platforms/workers-for-platforms/configuration/static-assets.mdx
@@ -0,0 +1,5 @@
+---
+pcx_content_type: navigation
+title: Static Assets
+external_link: /workers/static-assets/direct-upload/
+---
diff --git a/src/content/docs/workers/static-assets/direct-upload.mdx b/src/content/docs/workers/static-assets/direct-upload.mdx
index be37acf487b6f6..478ae530bf44f4 100644
--- a/src/content/docs/workers/static-assets/direct-upload.mdx
+++ b/src/content/docs/workers/static-assets/direct-upload.mdx
@@ -16,15 +16,18 @@ import {
TabItem,
Tabs,
} from "~/components";
+import { Icon } from "astro-icon/components";
:::note
-Directly uploading assets via APIs is an advanced approach that most users will not need. Instead, we encourage users to deploy your Worker with [Wrangler](/workers/static-assets/get-started/#1-create-a-new-worker-project-using-the-cli).
+Directly uploading assets via APIs is an advanced approach which, unless you are building a programatic integration, most users will not need. Instead, we encourage users to deploy your Worker with [Wrangler](/workers/static-assets/get-started/#1-create-a-new-worker-project-using-the-cli).
:::
Our API empowers users to upload and include static assets as part of a Worker. These static assets can be served for free, and additionally, users can also fetch assets through an optional [assets binding](/workers/static-assets/binding/) to power more advanced applications. This guide will describe the process for attaching assets to your Worker directly with the API.
+
+
```mermaid
sequenceDiagram
participant User
@@ -33,6 +36,18 @@ sequenceDiagram
User<<->>Workers API: Upload files
POST /client/v4/accounts/:accountId/workers/assets/upload?base64=true
User<<->>Workers API: Upload script version
PUT /client/v4/accounts/:accountId/workers/scripts/:scriptName
```
+
+
+```mermaid
+sequenceDiagram
+ participant User
+ participant Workers API
+ User<<->>Workers API: Submit manifest
POST /client/v4/accounts/:accountId/workers/dispatch/namespaces/:dispatchNamespace/scripts/:scriptName/assets-upload-session
+ User<<->>Workers API: Upload files
POST /client/v4/accounts/:accountId/workers/assets/upload?base64=true
+ User<<->>Workers API: Upload script version
PUT /client/v4/accounts/:accountId/workers/dispatch/namespaces/:dispatchNamespace/scripts/:scriptName
+```
+
+
The asset upload flow can be distilled into three distinct phases:
@@ -48,6 +63,8 @@ The [manifest upload request](/api/resources/workers/subresources/scripts/subres
`hash` represents a 32 hexadecimal character hash of the file, while `size` is the size (in bytes) of the file.
+
+
```bash
curl -X POST https://api.cloudflare.com/client/v4/accounts/{account_id}/workers/scripts/{script_name}/assets-upload-session \
--header 'content-type: application/json' \
@@ -69,6 +86,31 @@ curl -X POST https://api.cloudflare.com/client/v4/accounts/{account_id}/workers/
}
}'
```
+
+
+```bash
+curl -X POST https://api.cloudflare.com/client/v4/accounts/{account_id}/workers/dispatch/namespaces/{dispatch_namespace}/scripts/{script_name}/assets-upload-session \
+--header 'content-type: application/json' \
+--header 'Authorization: Bearer ' \
+--data '{
+ "manifest": {
+ "/filea.html": {
+ "hash": "08f1dfda4574284ab3c21666d1",
+ "size": 12
+ },
+ "/fileb.html": {
+ "hash": "4f1c1af44620d531446ceef93f",
+ "size": 23
+ },
+ "/filec.html": {
+ "hash": "54995e302614e0523757a04ec1",
+ "size": 23
+ }
+ }
+}'
+```
+
+
The resulting response will contain a JWT, which provides authentication during file upload. The JWT is valid for one hour.
@@ -110,7 +152,7 @@ Once every file in the manifest has been uploaded, a status code of 201 will be
## Create/Deploy New Version
-[Script](/api/resources/workers/subresources/scripts/methods/update/) and [version](/api/resources/workers/subresources/scripts/subresources/versions/methods/create/) upload endpoints require specifying a metadata part in the form data. Here, we can provide the completion token from the previous (upload assets) step.
+[Script](/api/resources/workers/subresources/scripts/methods/update/), [Version](/api/resources/workers/subresources/scripts/subresources/versions/methods/create/), and [Workers for Platform script](/api/resources/workers_for_platforms/subresources/dispatch/subresources/namespaces/subresources/scripts/methods/update/) upload endpoints require specifying a metadata part in the form data. Here, we can provide the completion token from the previous (upload assets) step.
```bash title="Example Worker Metadata Specifying Completion Token"
{
@@ -181,6 +223,7 @@ import "node:process";
const accountId: string = ""; // Replace with your actual account ID
const filesDirectory: string = "assets"; // Adjust to your assets directory
const scriptName: string = "my-new-script"; // Replace with desired script name
+const dispatchNamespace: string = ""; // Replace with a dispatch namespace if using Workers for Platforms
interface FileMetadata {
hash: string;
@@ -320,16 +363,17 @@ async function scriptUpload(completionToken: string): Promise {
),
);
- const response = await fetch(
- `https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/scripts/${scriptName}`,
- {
- method: "PUT",
- headers: {
- Authorization: `Bearer ${process.env.CLOUDFLARE_API_TOKEN}`,
- },
- body: form,
+ const url = dispatchNamespace
+ ? `https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/dispatch/namespaces/${dispatchNamespace}/scripts/${scriptName}`
+ : `https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/scripts/${scriptName}`;
+
+ const response = await fetch(url, {
+ method: "PUT",
+ headers: {
+ Authorization: `Bearer ${process.env.CLOUDFLARE_API_TOKEN}`,
},
- );
+ body: form,
+ });
if (response.status != 200) {
throw new Error("unexpected status code");
@@ -344,17 +388,18 @@ async function startUploadSession(): Promise {
manifest: fileMetadata,
});
- const response = await fetch(
- `https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/scripts/${scriptName}/assets-upload-session`,
- {
- method: "POST",
- headers: {
- Authorization: `Bearer ${process.env.CLOUDFLARE_API_TOKEN}`,
- "Content-Type": "application/json",
- },
- body: requestBody,
+ const url = dispatchNamespace
+ ? `https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/dispatch/namespaces/${dispatchNamespace}/scripts/${scriptName}/assets-upload-session`
+ : `https://api.cloudflare.com/client/v4/accounts/${accountId}/workers/scripts/${scriptName}/assets-upload-session`;
+
+ const response = await fetch(url, {
+ method: "POST",
+ headers: {
+ Authorization: `Bearer ${process.env.CLOUDFLARE_API_TOKEN}`,
+ "Content-Type": "application/json",
},
- );
+ body: requestBody,
+ });
const data = (await response.json()) as UploadResponse;
const jwt = data.result.jwt;