How to deploy Nuxt.js(SSR with Express.js) to Vercel via Gitlab? - express

I have successfully built my app and only remain step is deploy to the host Vercel via my repo on Gitlab
I use Nuxt.js(SSR type) with server Express.js and Nuxt.js Now Builder to deploy host Vercel via repo Gitlab
This is structure
api/
--| index.js
now.json
nuxt.config.js
In index.js
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const products = require("./routes/product/products");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Import API Routes
app.use(products);
// Export the server middleware
module.exports = {
path: "/api",
handler: app
};
In now.json
{
"version": 2,
"builds": [
{
"src": "nuxt.config.js",
"use": "#nuxtjs/now-builder",
"config": {
"serverFiles": [
"package.json"
]
}
}
]
}
And in nuxt.config.js
...
serverMiddleware: [
// API middleware
"~/api/index.js"
]
...
According to Vercel documentation, deploying is very easy, just commit and push code to Gitlab to complete
However, i always get error as below
I don't understand why? I don't know what i missed. Please help me and i'm very grateful for the help

narze, thank you for your solution, unfortunately it didn't work for me but pointed me in the right direction.
Here is my working now.json:
{
"version": 2,
"env": {
"ON_VERCEL": "true"
},
"builds": [
{
"src": "api/**/*.js",
"use": "#now/node"
},
{
"src": "nuxt.config.js",
"use": "#nuxtjs/now-builder"
}
],
"routes": [
{ "src": "/api/(.*)", "dest": "api/index.js" },
{ "src": "/api", "dest": "api/index.js" },
{ "src": "/(.*)", "dest": "$1" }
]
}
serverMiddleware in nuxt.config.js
serverMiddleware: isServerlessEnvironment ? [] : [
'~/api/index.js'
],
where isServerlessEnvironment defined on the very top of nuxt.config.js as
const isServerlessEnvironment = process.env.ON_VERCEL=="true"
API files need to be compiled with #now/node.
Routes need to be set up to separate nuxt routes from api routes.
With conditional isServerlessEnvironment in nuxt.config.js it works on local server with yarn dev and vercel server.
Credits to this article: Nuxt.js with an Express.js API server running on Now.sh
Thank you all for being helpful :)

I have similar problem with deploying Nuxt on Vercel with serverMiddleware's which returned 405 (Not Allowed). I solved it using this doc Nuxt Vercel Builder by specifying property serverFiles in vercel.json:
{
"builds": [
{
"src": "nuxt.config.js",
"use": "#nuxtjs/vercel-builder",
"config": {
"serverFiles": ["server-middleware/**"]
}
}
]
}
If you need to include files in the server lambda that are not built
by webpack or within static/, such as a local module or
serverMiddleware, you may specify them with this option. Each item can
be a glob pattern.

I know it's a bit late now lol. But I wrote an article to demonstrate the whole process to get your app up and running on Vercel. You can find it here.

Related

Timeout due to parsing Nuxt Content documents every cold start in Vercel server

I've a web built with Nuxt 2 deployed in Vercel where I'm using the #nuxt/content module for rendering some articles. It's using SSR and target: server, and everytime the server hibernates due to lack of activity, the first load takes +10 seconds or directly returns a timeout.
It's caused because when the server does the cold start, it is parsing the documents again reaching the time limit. I'm not sure why is this happening and how can I fix it. I guess moving to ssr: false can maybe help but I'm afraid my SEO can be affected. I believe a better solution should exist just to avoid re-parsing the documents everytime it does a cold start.
Nuxt version: 2.15.7
#nuxt/content version: 1.14.0
#nuxtjs/vercel-builder version: 0.22.1
Running on Node 16
Parsing documents at cold start
nuxt.config.js
export default {
ssr: true,
target: "server",
plugins: [
"#/plugins/articleManager.ts",
"#/plugins/leaflet.client.js",
"#/plugins/device.server.js",
],
components: true,
buildModules: [
"#nuxt/typescript-build",
"#nuxtjs/vuetify",
"vue-ssr-carousel/nuxt",
],
modules: [
"#nuxtjs/pwa",
"#nuxt/content",
"#nuxtjs/sitemap",
"#nuxtjs/robots",
"#nuxt/image",
],
content: {
fullTextSearchFields: ["title", "description"],
},
build: {
build: {
extend(config, { isClient }) {
if (isClient) {
config.devtool = "source-map";
}
},
},
},
srcDir: "src/",
};
vercel.json
{
"version": 2,
"builds": [
{
"src": "package.json",
"use": "#vercel/node"
},
{
"src": "nuxt.config.js",
"use": "#nuxtjs/vercel-builder",
"config": {
"serverFiles": [
".nuxt/content/**",
"src/content/**",
"server/**",
".nuxt/dist/sitemap-routes.json"
]
}
}
]
}
I've tried many configurations to avoid the server parsing the documents every cold start but didn't succed. I also tried keep ssr: true with target: static but didn't managed to make it work. And even if it worked, I doubt that would solve the problem.
Thanks!

VueJS PWA: service worker nog working. Maybe due to .htaccess file?

I've build a PWA with vue. Everything is working fine in development and when I deploy to chrome webserver. Service worker is registrated and running. So far so good.
When I deploy to production, service worker isn't running due to the fact that the scope or start_url is not matching manifest.json (thats what google dev tools tells me).
I believe it's due to the fact that I'm running vue-router in history mode and have a .htaccess file running on production to rewrite rules as recommended here.
I've also tested this to switch back to hash mode in vue-router and deploy to production again. Then service worker is working just fine.
To overcome this problem I've tried to set the scope in manifest.json and service worker to index.html:
register(`${process.env.BASE_URL}service-worker.js`, {
registrationOptions: { scope: 'index.html' },
ready () {
console.log(
'App is being served from cache by a service worker.\n'
)
}
})
The same for manifest.json:
{
"name": "myapp",
"short_name": "myapp",
"theme_color": "#4DBA87",
"icons": [
{ "src": "./img/icons/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "./img/icons/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" },
{ "src": "./img/icons/android-chrome-maskable-192x192.png", "sizes": "192x192", "type": "image/png", "purpose": "maskable" },
{ "src": "./img/icons/android-chrome-maskable-512x512.png", "sizes": "512x512", "type": "image/png", "purpose": "maskable" }
],
"start_url": "index.html",
"scope": "index.html",
"orientation": "portrait",
"display": "standalone",
"background_color": "#000000"
}
But still chrome gives me the message about scope being not in sync.
Any thoughts on this?
Add to package.json config for pwa plugin:
"vue": {
"pwa": {
"workboxOptions": {
"exclude": [
".htaccess"
]
}
}
}
UPDATE:
This action excludes .htaccess file from SW cache.
So, your SW won't crash and won't attempt to download .htaccess file from server.
At least, I faced with same problem and found this StackOverflow topic without answer. So, I read Vue PWA doc and found this, working for me, way.

Strapi GraphQL API - 405 Method Not Allowed

I've just deployed my Strapi API to production following the docs: https://strapi.io/documentation/v3.x/deployment/heroku.html
And by making POST requests from other origins, I get this error:
Since my API works finally on development (localhost to localhost) I presume that the issue is related to CORS, and if it's, that's the cors configuration that I've set on the API:
config/env/production/security.json:
{
"cors": {
"enabled": true,
"origin": "*"
}
}
config/env/production/middleware.js:
module.exports = {
settings: {
cors: {
enabled: true,
origin: "*",
},
},
};
I was added the cors config on the development environment...
In order to change the cors config on the production environment, the above code should be placed on the following path:
config/env/production/security.json
config/env/production/middleware.js
For me it was missing route in api/blog/config/routes.json
{
"method": "POST",
"path": "/blog",
"handler": "blog.create",
"config": {
"policies": []
}
},
In my case, since I use GraphQL for queries I should add /graphql at the end of the production URL as we do for localhost:1337/graphql.

How to do module name alias for third party package

I have a app that created by react-native init command.
My app import websocket package which in turn require http package and cause error said "Unable to resolve module http".
i.e: myApp -> 3rd-module -> ws -> http
I try to work-around by install "#tradle/react-native-http", and added follow lines to my app's package json file:
"browser": { "http": "#tradle/react-native-http" },
"react-native": { "http": "#tradle/react-native-http" },
but it doesn't work.
I also try using babel-plugin-module-resolver but unluck either. Here is my .babelrc :
{
"presets": ["module:metro-react-native-babel-preset"],
"plugins": [
[
"#babel/plugin-proposal-decorators",
{
"legacy": true
}
],
["module-resolver", {
"alias": {
"#tradle/react-native-http": "http"
}
}]
]
}
How to do alias for my case? I research to fixing this problem by using webpack configuration, but don't know where is the configure file. After google, i think project created by react-native init use metro config instead of webpack.
try
["module-resolver", {
"alias": {
"http":"#tradle/react-native-http"
}
}]

Loopback - redirect all traffic to index.html

I'm building a react single page application using for backend, loopback.
How can I set, in the middleware, all the traffic (except API calls to the server and asset files like css, js,...) to go to index.html?
Here is what I have for the moment in my middleware.json configuration for the files page.:
"files": {
"loopback#static": [
{
"paths": [
"/storage"
],
"params": "$!../storage"
},
{
"paths": [
"/*"
],
"params": "$!../client/index.html"
},
{
"paths": [
"/*.*"
],
"params": "$!../client"
}
]
},
At the moment, it seems like all traffic is indeed redirected to index.html but so are the css, js, ...
Any ideas?