Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkg/project/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ func (p *Project) EnvFor(ctx context.Context, complete *CompleteEvent, name stri
}
if dev.Cloudflare != nil && dev.Cloudflare.Path != "" {
env["SST_WRANGLER_PATH"] = dev.Cloudflare.Path
env["CLOUDFLARE_VITE_WRANGLER_CONFIG_PATH"] = dev.Cloudflare.Path
}
// Pass Cloudflare credentials to the child process for remote bindings
for _, key := range []string{"CLOUDFLARE_API_TOKEN", "CLOUDFLARE_API_KEY", "CLOUDFLARE_EMAIL", "CLOUDFLARE_DEFAULT_ACCOUNT_ID"} {
Expand Down
15 changes: 2 additions & 13 deletions platform/src/components/cloudflare/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,19 +173,6 @@ export interface AstroArgs extends SsrSiteArgs {
* });
* ```
*
* Add this to your `astro.config.mjs` for SST to work correctly.
*
* ```js title="astro.config.mjs"
* import { defineConfig } from "astro/config";
* import cloudflare from "@astrojs/cloudflare";
*
* export default defineConfig({
* adapter: cloudflare({
* configPath: process.env.SST_WRANGLER_PATH,
* }),
* });
* ```
*
* Use `sst/resource` for linked resources.
*
* ```astro title="src/pages/index.astro"
Expand Down Expand Up @@ -217,6 +204,8 @@ export class Astro extends SsrSite {
sitePath,
configName: "astro.config",
componentName: "Astro",
packageName: "@astrojs/cloudflare",
minVersion: "13.1.11",
});
}
validateNoWranglerFile(sitePath, "Astro");
Expand Down
50 changes: 38 additions & 12 deletions platform/src/components/cloudflare/helpers/validation.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import fs from "fs";
import path from "path";
import { VisibleError } from "../../error.js";
import { isALteB } from "../../util/compare-semver.js";
import { getPackageVersion } from "../../util/package.js";

/**
* Validates that no wrangler configuration file exists in the site directory.
Expand All @@ -27,13 +29,26 @@ export function validateNoWranglerFile(sitePath: string, componentName: string):
/**
* Validates that the framework config file contains the required SST_WRANGLER_PATH configuration.
* This ensures linked resources work correctly in Cloudflare SSR sites.
*
* Starting with the specified minimum version, the plugin automatically detects the SST-managed
* Wrangler config, so this validation is only needed for older versions.
*/
export function validateFrameworkConfig(input: {
sitePath: string;
configName: string;
componentName: string;
packageName: string;
minVersion: string;
}): void {
const { sitePath, configName, componentName } = input;
const { sitePath, configName, componentName, packageName, minVersion } = input;

// Check the package version first
const packageVersion = getPackageVersion(sitePath, packageName);

// If version is the minimum or higher, no validation needed (plugin auto-detects SST config)
if (packageVersion && isALteB(minVersion, packageVersion)) {
return;
}

const extensions = [".ts", ".js", ".mjs"];
const configDir = sitePath;
Expand All @@ -58,17 +73,28 @@ export function validateFrameworkConfig(input: {
const content = fs.readFileSync(configPath, "utf-8");
const hasWranglerPath = /configPath\s*[:=]\s*process\.env\.SST_WRANGLER_PATH/.test(content);

if (!hasWranglerPath) {
throw new VisibleError(
[
`Missing required configuration for ${componentName}.`,
"",
`The Cloudflare adapter must be configured with:`,
` configPath: process.env.SST_WRANGLER_PATH,`,
"",
`This is required for linked resources to work correctly:`,
`https://sst.dev/docs/cloudflare/#cloudflare-vite-plugin`,
].join("\n")
if (hasWranglerPath) {
// Show warning for backwards compatibility - user has old config but env var is present
console.warn(
`Starting with ${packageName} v${minVersion}, you no longer need to set configPath: process.env.SST_WRANGLER_PATH in your config file for ${componentName}. The plugin now automatically detects the SST-managed Wrangler configuration. You can safely remove this configuration.`
);
return;
}

// No env var set and version is old or unknown - require upgrade
throw new VisibleError(
[
`Please upgrade ${packageName} to v${minVersion} or higher for SST to work correctly with ${componentName}.`,
"",
packageVersion
? `Detected ${packageName} v${packageVersion}.`
: `Could not detect ${packageName} version in package.json.`,
"",
`Starting with v${minVersion}, the plugin automatically detects the SST-managed Wrangler configuration.`,
"Alternatively, you can add the following to your config file for older versions:",
` configPath: process.env.SST_WRANGLER_PATH,`,
"",
`https://sst.dev/docs/cloudflare/#cloudflare-vite-plugin`,
].join("\n")
);
}
20 changes: 2 additions & 18 deletions platform/src/components/cloudflare/react-router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,24 +174,6 @@ export interface ReactRouterArgs extends SsrSiteArgs {
* });
* ```
*
* Add this to your `vite.config.ts` for SST to work correctly.
*
* ```ts title="vite.config.ts"
* import { reactRouter } from "@react-router/dev/vite";
* import { cloudflare } from "@cloudflare/vite-plugin";
* import { defineConfig } from "vite";
*
* export default defineConfig({
* plugins: [
* cloudflare({
* viteEnvironment: { name: "ssr" },
* configPath: process.env.SST_WRANGLER_PATH,
* }),
* reactRouter(),
* ],
* });
* ```
*
* Use `sst/resource` for linked resources.
*
* ```ts title="app/routes/home.tsx"
Expand All @@ -217,6 +199,8 @@ export class ReactRouter extends SsrSite {
sitePath,
configName: "vite.config",
componentName: "ReactRouter",
packageName: "@cloudflare/vite-plugin",
minVersion: "1.33.0",
});
validateNoWranglerFile(sitePath, "ReactRouter");
}
Expand Down
1 change: 1 addition & 0 deletions platform/src/components/cloudflare/ssr-site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export abstract class SsrSite extends Component implements Link.Linkable {
function resolveBuildEnvironment() {
return resolveBuildWranglerPath().apply((wranglerPath) => ({
SST_WRANGLER_PATH: wranglerPath,
CLOUDFLARE_VITE_WRANGLER_CONFIG_PATH: wranglerPath,
}));
}

Expand Down
20 changes: 2 additions & 18 deletions platform/src/components/cloudflare/tan-stack-start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,24 +175,6 @@ export interface TanStackStartArgs extends SsrSiteArgs {
* });
* ```
*
* Add this to your `vite.config.ts` for SST to work correctly.
*
* ```ts title="vite.config.ts"
* import { defineConfig } from 'vite'
* import { tanstackStart } from '@tanstack/react-start/plugin/vite'
* import { cloudflare } from '@cloudflare/vite-plugin'
*
* export default defineConfig({
* plugins: [
* cloudflare({
* viteEnvironment: { name: 'ssr' },
* configPath: process.env.SST_WRANGLER_PATH,
* }),
* tanstackStart(),
* ],
* })
* ```
*
* Use `sst/resource` for linked resources.
*
* ```ts title="src/routes/api.ts"
Expand All @@ -215,6 +197,8 @@ export class TanStackStart extends SsrSite {
sitePath,
configName: "vite.config",
componentName: "TanStackStart",
packageName: "@cloudflare/vite-plugin",
minVersion: "1.33.0",
});
validateNoWranglerFile(sitePath, "TanStackStart");
}
Expand Down
14 changes: 4 additions & 10 deletions www/src/content/docs/docs/cloudflare.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -138,32 +138,26 @@ If you are using Cloudflare DNS with SST, use [`sst.cloudflare.dns`](/docs/compo

## Cloudflare Vite plugin

Cloudflare SSR components like [Astro](/docs/component/cloudflare/astro/) or [TanStack Start](/docs/component/cloudflare/tanstack-start/) need the Cloudflare Vite plugin to work correctly.
Cloudflare SSR components like [Astro](/docs/component/cloudflare/astro/), [TanStack Start](/docs/component/cloudflare/tanstack-start/), or [React Router](/docs/component/cloudflare/react-router/) need the Cloudflare Vite plugin to work correctly.

:::caution
Do not include any Wrangler configuration files (`wrangler.toml`, `wrangler.json`) in your project. SST manages these for you and will generate them as needed.
:::

You need to configure the Vite plugin to use the SST-managed Wrangler config.
Configure the Vite plugin as you will when deploying to Cloudflare:

```ts title="vite.config.ts"
import { defineConfig } from "vite";
import { cloudflare } from "@cloudflare/vite-plugin";

export default defineConfig({
plugins: [
cloudflare({
configPath: process.env.SST_WRANGLER_CONFIG,
}),
cloudflare(),
],
});
```

This environment variable is set by SST and ensures the plugin uses the generated Wrangler configuration.

:::tip
There is an [open PR](https://github.com/cloudflare/workers-sdk/pull/13587) on the Cloudflare Workers SDK that will add automatic detection of the SST-managed Wrangler config. Once merged, you won't need to explicitly set `configPath`.
:::
SST automatically sets the `CLOUDFLARE_VITE_WRANGLER_CONFIG_PATH` variable when deploying, pointing to the Wrangler configuration generated by SST.

---

Expand Down
Loading