Skip to content

feat: configure edge function at route level #12323

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 15 commits into
base: main
Choose a base branch
from
5 changes: 5 additions & 0 deletions .changeset/modern-scissors-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/adapter-netlify': minor
---

feat: configure edge function at route level
17 changes: 16 additions & 1 deletion documentation/docs/25-build-and-deploy/80-adapter-netlify.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,22 @@ New projects will use the current Node LTS version by default. However, if you'r

## Netlify Edge Functions

SvelteKit supports [Netlify Edge Functions](https://docs.netlify.com/netlify-labs/experimental-features/edge-functions/). If you pass the option `edge: true` to the `adapter` function, server-side rendering will happen in a Deno-based edge function that's deployed close to the site visitor. If set to `false` (the default), the site will deploy to Node-based Netlify Functions.
SvelteKit supports [Netlify Edge Functions](https://docs.netlify.com/netlify-labs/experimental-features/edge-functions/). To control how your routes are deployed to Netlify as functions, you can export const config inside +server.js, +page(.server).js and +layout(.server).js files.

For example you could deploy some parts of your app as Edge Functions...

```js
// @errors: 2307
/// file: about/+page.js
/** @type {import('@sveltejs/adapter-netlify').Config} */
export const config = {
runtime: 'edge'
};
```

...and others as Serverless Functions (note that by specifying config inside a layout, it applies to all child pages).

If you pass the option `edge: true` to the `adapter` function, server-side rendering will happen in a Deno-based edge function that's deployed close to the site visitor for all pages. If set to `false` (the default), the site will deploy to Node-based Netlify Functions.

```js
// @errors: 2307
Expand Down
8 changes: 8 additions & 0 deletions packages/adapter-netlify/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,11 @@ import { Adapter } from '@sveltejs/kit';
import './ambient.js';

export default function plugin(opts?: { split?: boolean; edge?: boolean }): Adapter;

export interface Config {
/**
* Whether to use [Edge Functions](https://docs.netlify.com/edge-functions/overview/) (`'edge'`)
* @default undefined
*/
runtime?: 'edge';
}
28 changes: 25 additions & 3 deletions packages/adapter-netlify/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,29 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) {
if (split) {
throw new Error('Cannot use `split: true` alongside `edge: true`');
}
}

/** @type {{ edge: import('@sveltejs/kit').RouteDefinition<import('./index.js').Config>[], lambda: import('@sveltejs/kit').RouteDefinition<import('./index.js').Config>[] }} */
const mutated_routes = { edge: [], lambda: [] };
for (let i = 0; i < builder.routes.length; i++) {
/** @type {import('@sveltejs/kit').RouteDefinition<import('./index.js').Config>} */
const route = builder.routes[i];

if (route.config?.runtime === 'edge') {
mutated_routes.edge.push(route);
} else {
mutated_routes.lambda.push(route);
}
}

if (mutated_routes.edge.length) {
builder.routes = mutated_routes.edge;
await generate_edge_functions({ builder });
} else {
generate_lambda_functions({ builder, split, publish });
}

if (mutated_routes.lambda.length) {
builder.routes = mutated_routes.lambda;
generate_lambda_functions({ builder, publish, split });
}
},

Expand Down Expand Up @@ -204,7 +223,10 @@ function generate_lambda_functions({ builder, publish, split }) {
builder.copy(`${files}/esm`, '.netlify', { replace });

// Configuring the function to use ESM as the output format.
const fn_config = JSON.stringify({ config: { nodeModuleFormat: 'esm' }, version: 1 });
const fn_config = JSON.stringify({
config: { nodeModuleFormat: 'esm' },
version: 1
});

builder.log.minor('Generating serverless functions...');

Expand Down
Loading