Search code examples
javascriptnode.jsexpressaxiosvercel

Having problem deploying express server on vercel [404 page not found]


I tried to deploy my express server on vercel to solve cors problem on my front code.

The problem is 404 error pops up when I enter the deployed page:

but it goes well when I try on localhost.

// vercel.json       
{
      "version": 2,
      "builds": [
        {
          "src": "./index.js",
          "use": "@vercel/node"
        }
      ],
      "routes": [
        {
          "src": "/(.*)",
          "dest": "/"
        }
      ],
      "rewrites": [{ "source": "/api/(.*)", "destination": "/api" }]
    }

//index.js
const express = require("express");
const cors = require("cors");
const axios = require("axios");

const app = express();

const PORT = process.env.PORT || 3000;
require("dotenv").config();

let corsOptions = {
  origin: ["http://localhost:3000", "https://humanscape-team5a.netlify.app"],
};

app.use(cors(corsOptions));

app.get("/", (req, res) => {
  const textQuery = req.query.searchText;
  const numOfRowsQuery = req.query.numOfRows;

  axios
    .get(
      "http://apis.data.go.kr/B551182/diseaseInfoService/getDissNameCodeList",
      {
        params: {
          sickType: 1,
          medTp: 2,
          diseaseType: "SICK_NM",
          searchText: textQuery,
          ServiceKey: process.env.KEY,
          numOfRows: numOfRowsQuery,
          _type: "json",
        },
      }
    )
    .then(response => res.send(response.data));
});

app.listen(PORT, () => {
  console.log(`Server running on ${PORT}`);
});

As it works on localhost, I guess it is kind of vercel setting problem. Any thoughts?


Solution

  • Not sure if you're still looking for a solution, but I did resolve this after some significant trial and error.

    First and foremost, vercel seems to require an /api folder with an index.js file in it to work. Originally, I got confused because my index.js file was also used to start my server when working locally. Vercel is basically taking the place of whatever your server file is locally. You should still leave this for local testing, but you can basically ignore it when working with vercel.

    In your /api/index.js file you will house your routes.

    ./api/index.js
    
    var createError = require('http-errors');
    var express = require('express');
    var path = require('path');
    var cookieParser = require('cookie-parser');
    var logger = require('morgan');
    
    var indexRouter = require('../routes/index');
    
    var app = express();
    
    const whitelist = [
      '*'
    ];
    
    app.use((req, res, next) => {
      const origin = req.get('referer');
      const isWhitelisted = whitelist.find((w) => origin && origin.includes(w));
      if (isWhitelisted) {
        res.setHeader('Access-Control-Allow-Origin', '*');
        res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
        res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,Content-Type,Authorization');
        res.setHeader('Access-Control-Allow-Credentials', true);
      }
      // Pass to next layer of middleware
      if (req.method === 'OPTIONS') res.sendStatus(200);
      else next();
    });
    
    const setContext = (req, res, next) => {
      if (!req.context) req.context = {};
      next();
    };
    app.use(setContext);
    
    app.use('/', indexRouter);
    
    module.exports = app;
    
    

    and my vercel.json file is...

    // vercel.json
    
    {
       "version": 2,
       "builds": [
        {
            "src": "./index.js",
            "use": "@vercel/node"
        }
       ],
       "routes": [
        {
            "src": "/(.*)",
            "dest": "/"
        }
       ]
    }
    

    Not sure if this is helpful, but this worked for me. The big thing is nesting your index.js routes file in an api folder.