Useful Snippets

Welcome!


This blog is used to collect useful snippets related to Linux, PHP, MySQL and more. Feel free to post comments with improvements or questions!

Are your smart devices spying on you? Make better purchasing choices and find products that respect your privacy at Unwanted.cloud

RSS Latest posts from my personal blog


Subscribe to RSS feed


Configure CORS in SvelteKit to make fetch requests to your API routes from a different host

Stanislav KhromovStanislav Khromov

Out of the box, SvelteKit does not set any CORS headers on its API routes (+server.js/ts), so if you have your regular non-Svelte site on the domain example.com and a SvelteKit instance on svelte.example.com then your site on example.com won’t be able to make fetch/AJAX requests to SvelteKit.

To fix this, let’s see how we can allow requests from any site:

First, create the file hooks.server.ts See documentation

Add the following code. Note: This will add Access-Control-Allow-Origin: * to all requests under /api. So your API routes need to be under src/routes/api/...

import type { Handle } from '@sveltejs/kit';

export const handle: Handle = async ({ resolve, event }) => {

  // Apply CORS header for API routes
  if (event.url.pathname.startsWith('/api')) {
    // Required for CORS to work
    if(event.request.method === 'OPTIONS') {
      return new Response(null, {
        headers: {
          'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Headers': '*',
        }
      });
    }
  }

  const response = await resolve(event);
  if (event.url.pathname.startsWith('/api')) {
        response.headers.append('Access-Control-Allow-Origin', `*`);
  }
  return response;
};

This will allow CORS from any website, so you might want to tighten up these rules in production. For example if you want to allow only *.example.com to access CORS you can adapt the above code like this. This will send back Access-Control-Allow-Origin: yourhostname.example.com instead of *.

// Inside handle()
const validDomains = /^(.*)?\.?example\.com$/;
let cors = false;

let originDomain = null;
try {
    originDomain = new URL(event.request.headers.get('origin') || '').hostname;
    if(validDomains.test(originDomain)) {   
        cors = `https://${originDomain}`
    }
} catch (e) {
    console.log('Invalid origin', e);
}

//...
if(event.request.method === 'OPTIONS' && cors) {
    return new Response(null, {
      headers: {
          'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
          'Access-Control-Allow-Origin': cors,
          'Access-Control-Allow-Headers': '*'
      }
   });
}

//... 
response.headers.append('Access-Control-Allow-Origin', cors);

Full-stack impostor syndrome sufferer & Software Engineer at Schibsted Media Group

Comments 5
  • Ilja
    Posted on

    Ilja Ilja

    Reply Author

    Thank you for this post! It just saved my day.


  • tom
    Posted on

    tom tom

    Reply Author

    Hey! Is it possible to setup CORS to use different port for backend? My sveltekit app running on 5713, but my backend rest api is on localhost:9000.


    • Stanislav Khromov
      Posted on

      Stanislav Khromov Stanislav Khromov

      Reply Author

      Hi Tom!

      This tutorial is for connecting any *other* app to your SvelteKit app.

      If you are connecting your SvelteKit app to another service at localhost:9000, you will need to set the equivalent headers in the application running on port 9000. There is nothing SvelteKit can help with here because it does not handle CORS in this interaction.


  • Bruno
    Posted on

    Bruno Bruno

    Reply Author

    thanks


  • Quang
    Posted on

    Quang Quang

    Reply Author

    Thank you