I have been making some websites using Sapper together with Verce (formerly known as ZEIT) and think it’s a fantastic combination. Vercel is being used as deployment for my Sapper app.
I have however run into some trouble with my API routes when I run a local production build or — of course I deploy my application with Vercel. The problem has been that my API routes returns a 404 and can’t be found.
A simple project
Picture the following default Sapper folder setup — besides api/cats.js
that is:
src/
routes/
api/
cats.js
_error.svelte
_layout.svelte
index.svelte
client.js
server.js
template.js
Let’s say in my index.svelte
I want to call a fetch(api/cats.js)
and get my favorite cats in a fine list. This works fine when running locally.
However, when I run my code in a production build and call that very same route, it returns a 404.
Why is this happening?
I have been searching through every StackOverflow and GitHub issue I could find and came back empty handed. When I did the most obvious thing and went to the Sapper Docs I found a very hidden gem to why this is.
When you run
sapper export
, Sapper first builds a production version of your app, as though you had runsapper build
, and copies the contents of yourstatic
folder to the destination. It then starts the server, and navigates to the root of your app. From there, it follows any<a>
,<img>
,<link>
and<source>
elements it finds pointing to local URLs, and captures any data served by the app.Because of this, any pages you want to be included in the exported site must either be reachable by
<a>
elements or added to the--entry
option of thesapper export
command.
This means that my fetch-call to api/cats isn’t there — because it’s not a natural source through a
, img
, link
or source
-tags.
The solution
In the package.json
you have to modify your build
script to make api/cats
reachable. Like this:
"scripts": {
"build": "sapper export --entry \"index api/menu\"",
...scripts
},
That little --entry
flag collects the routes that should be reachable to the user — call it a whitelist of routes.
Important!
As you can see I also add index
there because this DOES NOT work together with scraping the a
, img
, link
or source
-tags. You either use the first more automatic solution OR the — entry
flag.
Hope this helps those in need (and those who hasn’t read the documentation of Sapper)
Sincerly,
Oliver – Senior frontend developer