Vercel/NextJS: How to access serverless functions from frontend during local development?

Viewed 1840

My React/NextJS front end has a Button component that fetches data via a serverless function when the button is clicked. I want to test this functionality during local development with the Vercel dev/CLI tools. I am getting a 404 result when attempting to access my lambda functions. Here are the approximate steps that I've gone through so far:

  1. Create package.json with a dev script:
...
"scripts": {
    "dev": "yarn codegen && next --hostname=0.0.0.0 --port=3001",
}
...
  1. Link to deployed vercel project
  2. Create vercel.json to specify builds and routes:
...
    "builds": [
        { "src": "*.html", "use": "@now/static" },
        { "src": "pages/api/*.py", "use": "@now/python" },
    ],
    "routes": [
        { "src": "/api/validate", "dest": "/pages/api/validate.py" }
    ]
...
  1. Create my test Lambda function (in python):
from http.server import BaseHTTPRequestHandler
from datetime import datetime

class handler(BaseHTTPRequestHandler):

  def do_GET(self):
    self.send_response(200)
    self.send_header('Content-type', 'text/plain')
    self.end_headers()
    self.wfile.write(str(datetime.now().strftime('%Y-%m-%d %H:%M:%S')).encode())
    return
  1. Create my Button component:
...
    <Button
        variant="contained"
        color="secondary"
        onClick={() => {
            fetch('api/validate')
                .then(response => { console.log(response)
                    response.json() })
                .then(data => console.log(data))
        }}
    >
        Generate sample dataset
    </Button>
...
  1. Run vercel dev
  2. Access website at localhost:3001 (next dev server address)
  3. Click button

Result:

I'm receiving a 404 response

Note: I can access the lambda function from localhost:3000/pages/api/validate.py (vercel dev server address). This appears to manually kickstart the lambda function build and serve process. I thought that it should have been built and served already from the vercel.json specification and be available at localhost:3001/api/validate. This seems to agree with the Vercel documentation.

Note 2: Next dev/CLI tools build and serve javascript/typescript files just fine. I'm using python and Go functions as well, which are supported by Vercel dev/CLI but not Next

2 Answers

My solution was to use vercel dev instead of next dev or yarn dev, and to use an environment variable in a .env file that points to the function url. This env variable should be prepended with NEXT_PUBLIC_ so that it is registered by next.js and passed to process.env during the build process.

# .env
NEXT_PUBLIC_FUNCTIONS_BASE_URL="http://localhost:3000" # 3000 is vercel port
# component.js
...
fetch(process.env.NEXT_PUBLIC_FUNCTIONS_BASE_URL + '/api/function-name')
...

You need to pass the port from vercel dev to the upstream CLI, in this case next dev.

{
  "scripts": {
    "dev": "yarn codegen && next dev --port=$PORT",
  }
}

Now when you run vercel dev, the ephemeral port will be proxied from the dev server.

You can also remove vercel.json if you rename /pages/api to /api.

Related