6

I'm actually building a basic svelkit app. I need to fetch to a weather api but impossible to fetch I have cors errors : enter image description here

I guess I need to setup a proxy for https://www.metaweather.com is there any way to do it with svelte kit ?

General Grievance
  • 4,555
  • 31
  • 31
  • 45
JuleZ
  • 216
  • 3
  • 11

1 Answers1

20

There certainly is. SvelteKit routing provides two types of routes, pages (= frontend) and endpoints (= backend).

Quoting the SvelteKit routing docs:

Endpoints run only on the server (or when you build your site, if prerendering). This means it's the place to do things like access databases or APIs that require private credentials or return data that lives on a machine in your production network. Pages can request data from endpoints. Endpoints return JSON by default, though may also return data in other formats.

CORS is essentially a form of credentialed request, so having an endpoint acting as a proxy API is ideal.

This is what such a route would look like in your use case:

// src/routes/api/weather/[city].json.js
export async function get({ params }) {
    const { city } = params;

    const res = await fetch(`https://www.metaweather.com/api/location/search/?query=${city}`);
    const weather = await res.json();

    return { body: weather };    
}

SvelteKit Endpoints documentation detailing stuff like the expected format of the return object, handling POSTs requests, etc.

Once this route is up, you would access it in lieu of accessing the original API in your frontend code, for example:

fetch(`http://localhost:3000/api/weather/${city}.json`);

And that's pretty much all there is to it.

Important update for users of a newer release of SvelteKit

In newer releases of SvelteKit, following its switch to a slightly different routing convention, the endpoint above should now be located in src/routes/api/weather/[city].json/+server.js. Its content should still work as-is however. (No longer true, see below).

Update for SvelteKit 1.0+

The structure of an endpoint handler has slightly changed in SvelteKit's 1.0 release. A proxy route would now look like the following:

// src/routes/api/weather/[city].json/+server.js
export function GET({ params }) { // note the capitalized method name
    const { city } = params;

    // we can now simply pass on the original 3rd-party api response promise
    return fetch(`https://www.metaweather.com/api/location/search/?query=${city}`);
}
Thomas Hennes
  • 9,023
  • 3
  • 27
  • 36
  • 2
    I've looked at so many tutorials and SvelteKit's official documentation. Only your answer helped me. – NetOperator Wibby Sep 07 '22 at 00:03
  • 2
    @NetOperatorWibby Glad I could help! Your comment also reminded me to update the answer with a change in the name & location of the endpoint file to reflect changes in SvelteKit's routing convention in its more recent releases :) – Thomas Hennes Sep 07 '22 at 11:45
  • 2
    Further updated to conform to SvelteKit 1.0's endpoint handler format – Thomas Hennes Jan 27 '23 at 09:13
  • is it possible to provide help regarding setting a custom node server? It seems the team behind adapter-node abondened the community and no longer answering questions regarding the adapter. https://stackoverflow.com/questions/76733107/adapter-node-in-sveltekit-creating-and-using-custom-node-server-cors-error also my git is here https://github.com/fxmt2009/kitcustomserver how to make the build aware of my server and use it for the output/build instead of the vite during dev? – Marco Jul 21 '23 at 13:56