Skip to content
Merged
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
6 changes: 6 additions & 0 deletions .changeset/legal-boxes-eat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@sveltejs/adapter-netlify": patch
---

fix: copy `_redirects` when deploying edge function

27 changes: 11 additions & 16 deletions packages/adapter-netlify/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,18 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) {
builder.writeClient(publish_dir);
builder.writePrerendered(publish_dir);

// Copy user's custom _headers file if it exists
// Copy user's _headers file if it exists
if (existsSync('_headers')) {
builder.log.minor('Copying user custom headers...');
builder.copy('_headers', join(publish, '_headers'));
}

// Copy user's _redirects file if it exists
if (existsSync('_redirects')) {
builder.log.minor('Copying user redirects...');
builder.copy('_redirects', join(publish, '_redirects'));
}

builder.log.minor('Writing Netlify config...');
write_frameworks_config({ builder });

Expand All @@ -102,7 +109,7 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) {

await generate_edge_functions({ builder });
} else {
generate_serverless_functions(builder, publish, split);
generate_serverless_functions(builder, split);
}
},

Expand All @@ -115,20 +122,15 @@ export default function ({ split = false, edge = edge_set_in_env_var } = {}) {

/**
* @param {Builder} builder
* @param {string} publish
* @param {boolean} split
*/
function generate_serverless_functions(builder, publish, split) {
function generate_serverless_functions(builder, split) {
// https://docs.netlify.com/build/frameworks/frameworks-api/#netlifyv1functions
mkdirSync(netlify_framework_serverless_path, { recursive: true });

builder.writeServer('.netlify/v1/server');

const replace = {
'0SERVER': './server/index.js' // digit prefix prevents CJS build from using this as a variable name, which would also get replaced
};

builder.copy(files, '.netlify/v1', { replace, filter: (file) => !file.endsWith('edge.js') });
Comment on lines -127 to -131

@teemingc teemingc Sep 7, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We no longer have multiple serverless files so we can just copy the files/serverless.js one

builder.copy(`${files}/serverless.js`, '.netlify/v1/serverless.js');

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

Expand Down Expand Up @@ -210,13 +212,6 @@ function generate_serverless_functions(builder, publish, split) {
type: 'singular'
});
}

// Copy user's custom _redirects file if it exists
if (existsSync('_redirects')) {
builder.log.minor('Copying user redirects...');
const redirects_file = join(publish, '_redirects');
builder.copy('_redirects', redirects_file);
}
}

/**
Expand Down
8 changes: 8 additions & 0 deletions packages/adapter-netlify/test/apps/edge/build.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,11 @@ test('_headers are copied to publish directory', () => {
const headers = fs.readFileSync(path.resolve(import.meta.dirname, './build/_headers'), 'utf-8');
expect(headers).toContain('X-Custom-Header: test-value');
});

test('_redirects are copied to publish directory', () => {
const redirects = fs.readFileSync(
path.resolve(import.meta.dirname, './build/_redirects'),
'utf-8'
);
expect(redirects).toContain('/redirect-me /greeting/redirected 301');
});
Loading