Search code examples
javascriptnode.jsvue.jsvercel

Deploy Node.js Restfull API and Vue.js app at the same time


I want to deploy Node.js express API and Vue.js app in the same domain with Vercel in one project.

I have one Vue.js app in root folder and i have another folder in my root folder like ./api.

I tried this script in my package.json file(In my Vue.js app.):

"serve": "vue-cli-service serve && cd api && npm run start".

This is my Node.js app's package.json script:

"start": "node index.js"

But it not works. (I know the reason of "why it doesnt work".)

How can i deploy these 2 apps in the same project?

(So i want a API works like: example.com/api/urls)


Solution

  • Vercel is a serverless platform, while your usage of Express is "stateful", meaning you start a long-running server process that listens for requests. Serverless, on the other hand, consists of short-running processes that spawn as needed to handle requests.

    Check out this guide for using Express with Vercel: https://vercel.com/guides/using-express-with-vercel

    The simplest solution is to put your entire Express app into a single serverless function (even though this is an anti-pattern):

    // /api/index.js
    
    const app = require('express')()
    const { v4 } = require('uuid')
    
    app.get('/api', (req, res) => {
      const path = `/api/item/${v4()}`
      res.setHeader('Content-Type', 'text/html')
      res.setHeader('Cache-Control', 's-max-age=1, stale-while-revalidate')
      res.end(`Hello! Go to item: <a href="${path}">${path}</a>`)
    })
    
    app.get('/api/item/:slug', (req, res) => {
      const { slug } = req.params
      res.end(`Item: ${slug}`)
    })
    
    module.exports = app
    
    

    And ensure you set up a rewrite in your vercel.json:

    {
      "rewrites": [{ "source": "/api/(.*)", "destination": "/api" }]
    }
    

    (these code snippets are taken directly from the guide linked above – I highly recommend following it!)

    The better, serverless, approach would be to split your Express routes into their own serverless function that can be called on-demand.


    Additionally, your "serve" script starting the API is unnecessary, as the top-level API directory is zero-config with Vercel. You can simply use "serve": "vue-cli-service serve".