My project has a frontend and a backend deployed separately from 2 separate Github repos on "render.com".
It also has a Mongoose database for user credentials. But it is not the subject of this question.
All was working fine until I refreshed any page, I got 404 Not Found despite the configured proxy.
For instance, I redirect all my client-side links to "/" so that the user does not get the 404 Not Found page. At least it is more user friendly.
Here are some more details:
Frontend is a Vite react client:
Client Repo: https://github.com/Catevika/catevika_shoplineart-client
Render static site: https://shoplineart-afbr.onrender.com
Backend is an Express server:
Server Repo: https://github.com/Catevika/catevika_shoplineart-server
Render web service: https://shoplineart-api.onrender.com
Routes are managed client-side with react-router V6 but an authRoute for Login / Register.
File structure:
root
.. client
.. dist --> build folder with assets: pictures - ok in Render
.. src
.... api --> for Login
.... (...)
.. vite.config.js --> with proxy - ok in Render thanks to a Vite base URL variable
.. index.html --> outside "public" - specific to Vite
.. main.jsx
.. .env --> ok in Render
.. package.json
.. server
.. (...)
.. index.js
.. .env --> ok in Render
.. package.json --> type: "module" to use the "import" instead of "require"
vite.config.js:
import { defineConfig } from 'vite';
import react from '#vitejs/plugin-react';
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'https://shoplineart-api.onrender.com',
changeOrigin: true
}
}
},
plugins: [react()]
});
Express index.js:
import express from 'express';
import mongoose from 'mongoose';
import helmet from 'helmet';
import morgan from 'morgan';
import dotenv from 'dotenv';
import cors from 'cors';
import path from 'path';
import authRoute from './routes/authRoute.js';
dotenv.config();
const app = express();
app.use(cors());
mongoose.set('strictQuery', false);
mongoose.connect(process.env.MONGO_URI);
console.log('\x1b[33m', 'MongoDB connected successfully');
app.use(express.json());
app.use(helmet());
app.use(helmet.crossOriginResourcePolicy({ policy: 'cross-origin' }));
app.use(morgan('common'));
app.use('/', authRoute);
app.listen(process.env.EXPRESS_PORT, () =>
console.log('\x1b[33m', `Server running on port ${process.env.EXPRESS_PORT}`)
);
if (process.env.NODE_ENV === 'production') {
app.get('*', (req, res) =>
res.sendFile(path.resolve(__dirname, '../client', 'dist', 'index.html'))
);
}
I tried adding secure: false in vite.config.js.
It failed.
What am I missing?
Thanks a lot for your precious help. I am stuck...
Related
I am not able to load swagger for my nestJS application which is deployed on EKS.
Here is my main.ts
import {NestFactory} from '#nestjs/core';
import {NestExpressApplication} from '#nestjs/platform-express';
import {DocumentBuilder, SwaggerModule} from '#nestjs/swagger';
const swaggerUi = require('swagger-ui-express')
import {AppModule} from './app.module';
import {json, NextFunction, Request, Response} from 'express';
(async () => {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
const options = new DocumentBuilder()
.setTitle('Test')
.build();
const document = SwaggerModule.createDocument(app, options,{ ignoreGlobalPrefix: true
app.use("*/docs",swaggerUi.serve,swaggerUi.setup(document));
// Or
SwaggerModule.setup(`/docs`, app, document);
await app.listen(port, () => {
console.log(`Test service is running on port ${port}...`);
});
})
();
On my local machine the swagger doc loads correctly but when I deploy it to a development environment, it fails
dev url "https://dev-test-api.com/testservice/v1/docs/", it strips the /testservice/v1/ and redirects to "https://dev-test-api.com/docs/ and gives a 404.
I have tried couple of solutions mentioned in https://github.com/scottie1984/swagger-ui-express/issues/183
The forward-prefix option and the redirect too. None seem to work
Another problem I have is that the prefix "testservice/v1" changes as per different sandbox environments and since it is not an environment variable I don't have a way to set the path for swagger file before app is loaded.
I'm on Nuxt 2.15.8 and trying to build an offline app with electron.js and prisma+sqlite for local DB.
In nuxt to hit a local endpoint there is a common way of using serverMiddleware and express like this:
// api.js that will be added to nuxt.config.js file as serverMiddleware
import express from 'express'
const app = express()
app.use(express.json())
export default {
path: '/api',
handler: app
}
which send endpoints beginning with api/ through app handler which I can use to access my BD (the common way to access sqlite3 DB is the same)
// added to api.js
import { PrismaClient } from '../../resources/prisma/client'
const prisma = new PrismaClient()
app.get(`/user/info`, async (req, res) => {
const result = await prisma.user.findUnique({
where: {
id: 1,
},
})
console.console.log(res);
res.json(result)
})
this will work fine on nuxt, also fine on nuxt-electron dev mode. but on built exe file serverMiddleware won't be called. So as it has be done by others (nuxt-electron accessing offline local DB) there must be a way to define endpoints on client side. any idea??
Updated:
as I changed my Nuxt-Electron boilerplate I could access serverMiddleware in exe file but it wont hit the endpoints yet!
Nuxt in 2.13 released runtimeConfig and tells us to migrate from dotenv in this article
I created a .env file where i wrote my variables and made sure that is ignored in my .gitignore file.
In nuxt.config.js I added the fallowing
privateRuntimeConfig: {
apiKey: process.env.apiKey,
}
Like this I have access to my apiKey in nuxt.config.js and it works nice. However I use a plugin for google maps where I need to put my apiKey in my plugin js file I created. I'm trying something like this but I cant access to my .env variables.
import Vue from 'vue'
import x5GMaps from 'x5-gmaps'
export default ({ app }) => { Vue.use(x5GMaps, app.context.$config.apiKey) }
Try this:
export default ({ app }) => { Vue.use(x5GMaps, app.$config.apiKey) }
But it just work with publicteRuntimeConfig
I am trying to serve all routes to express with my dist folder.
app.use(expressStaticGzip('dist'));
app.get('*', (req,res) => {
res.sendFile(expressStaticGzip(path.join(`${__dirname}/dist/index.html`)));
});
When I run this code I got the error:
Internal Server Error
If I use route by route it works:
app.use('/', expressStaticGzip('dist'));
But I need the all routes.
I found the solution:
I switched expressStaticGzip to compression and used express-history-api-fallback:
import fallback from 'express-history-api-fallback';
import express from 'express';
import compression from 'compression';
...
app.use(compression());
const root = `${__dirname}/dist`
app.use(express.static(root));
app.use(fallback('index.html', { root })) ;
And I changed my relative imports at index.html for absolute imports ('./' to '/')
According to the docs, I should put routeAfterAuthentication in my config/environment.js file.
My environment.js contains the following:
module.exports = function(environment) {
var ENV = {
modulePrefix: 'client',
environment: environment,
baseURL: '',
locationType: 'auto',
routeAfterAuthentication: 'dashboard',
...
However, it's still not getting redirected to the dashboard route and showing that the index route is not defined.
Am I missing something here?
You will need to include ember-simple-auth key like this
var ENV = {
};
...
ENV['ember-simple-auth'] = {
authenticationRoute: 'sign-in',
routeAfterAuthentication: 'YOUR ROUTE GOES HERE'
}
...
You can also define them by environment inside if (environment === 'development'), but for all environments you can put them after var ENV declaration. It is also important to import application route mixin so that redirect works (app / routes / application.js)
import Ember from 'ember';
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin';
export default Ember.Route.extend(ApplicationRouteMixin, {});