Recently I migrated my personal website to Next.js and thought I had everything working well with Netlify, however on deployment I noticed an issue with the API data...
Background
As part of my migration from Gatsby to Next.js I moved the .gpx
data to a Next.js API end point so that I can easily access the data in multiple places. I'm currently using the data in a custom Leaflet map component on posts. Each <Map />
component requests the geo json data it needs and the renders the routes and elevation profiles.
The data is sourced from .gpx
files on the file system and then parsed into geo-json and served via the API.
Issue
When testing this in dev and on a local build/serve this all works well, and I can see a nice map and graph. However, in production the map doesn't show and the network displays a 500 error. Looking at the Netlify logs I see:
1ERROR Error: ENOENT: no such file or directory, scandir '/var/task/sites/carltophamcom/src/content' ...snip... INFO [GET] /api/geo-json/ffordd_pen_llech_formerly_steepest_road_in_the_world_234nodes (SSR)
From this it's clear that the Netlify functions can't find the .gpx
file. The most obvious issues are:
- The file names are case-sensitive on Linux, but not Mac (or Windows). My files are in the correct case!
- The files are committed to the repo!
After checking this I can dig deeper.
Resolution
Since I'm using functions, that is the likely cause.
As part of a function build, netlify bundles up all needed modules and files before deploying them, but looking at the logs, it's clear that the files are not there. So how does Netlify know what to bundle? Netlify doesn't know!. We need to tell netlify where the files are.
By adding an entry into the netlify.toml
we can include any files we need manually:
1[functions] included_files = ["sites/carltophamcom/src/content/articles/**/*.gpx"]
Now when Netlify builds the function it will automatically include the .gpx
files in the sites/carltophamcom/src/content/articles
sub folders.
After redeploying with this extra config, the API endpoint works successfully, and we can see the maps on the articles with a <Map />
component!