How to prevent Vercel routing to not finding the page - json

I am building a project using NextJs and Vercel, but, when the users try to access a new page or route, the Vercel gives them the 404 error.
In other projects, I used Netlify as router and this error was fixed using the netlify.toml config file, but, I am not able to do the same using the vercel.json file.
Can you guys help me to turn this file:
netlify.toml
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
Into a vercel.json config file?
I was trying with this settings:
vercel.json
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html"}]
}
But it did not solved my issue.

A workaround is to use a catch all route that immediately redirects to the index page. For example:
// [...404].jsx
export default function Page() {
return null;
}
export function getServerSideProps() {
return {
redirect: {
destination: '/',
permanent: false,
},
};
}

Related

sveltekit routes not working when deployed to server

Here's my svelte.config.js and I'm using adapter-static :
const config = {
kit: {
adapter: adapter({
// default options are shown
pages: '../backend/build',
assets: '../backend/build',
fallback: null,
precompress: false,
}),
alias: {},
appDir: '_app',
browser: {
hydrate: true,
router: true,
},
files: {
assets: 'static',
hooks: 'src/hooks',
lib: 'src/lib',
params: 'src/params',
routes: 'src/routes',
serviceWorker: 'src/service-worker',
template: 'src/app.html',
},
floc: false,
methodOverride: {
parameter: '_method',
allowed: [],
},
paths: {
assets: '',
base: '',
},
trailingSlash: 'always',
vite: {
server: {
proxy: {
'/api': 'http://localhost:5555',
},
},
},
},
preprocess: null,};
From the backend (Go lang) I'm serving build directory & index.html file. The homepage works fine but whenever I click on any route, it sends get request to the server instead of redirecting in the app itself.
Here's the go code to serve from backend:
router := gin.Default()
router.StaticFile("/", "./build/index.html")
router.StaticFS("/_app", http.Dir("build/_app"))
I have also tried with the following code:
router.NoRoute(func(c *gin.Context) {
path := c.Request.URL.Path
c.File("./build/index.html")
})
Note: Things work fine when I run npm run preview.
The adapter-static has two distinct modes of operation: SPA and prerendering. When there are several routes, both the npm run dev and npm run preview works as intended, but once built, the static routing falls to the web server, in your case, the Go framework, but the same happens with any other static server (I have tested also Nginx and Apache).
I found a workaround to avoid converting the site to a SPA: Installing a url rewrite mechanism as a middleware in order to add the .html extension that the static server is expecting in the compiled site. In my case, I used Go Fiber github.com/gofiber/rewrite/v2 and it worked as intended (the same behavior as when using npm run dev)
For Nginx static server the solution is the same url rewrite and it could be used as explained here: https://www.codesmite.com/article/clean-url-rewrites-using-nginx
The homepage works fine but whenever I click on any route, it sends get request to the server instead of redirecting in the app itself
SvelteKit users internal router, or $app/navigator for links only if it detects a link to be the same domain as the current page. Likely your web server is misconfigured and there is a mismatch of domain somewhere in
The web browser address bar
Web server configuration
However, the question do not contain these details and is thus unanswerable "why" and how to fix it.

How can I show image from express server on Vue app?

I'm currently having problem with displaying image from db. In my DB (Sequelize MySQL), my columns looks like this.
Database
You can see that there is path, which is showing path to file on server. (Express server using multer to upload photos).
How Am I able to show this on my frontend? I was trying everything, but I cannot figure solution.
When I open my server folder and copy path of file there, I get path like this:
Path
When I put it in chrome, I can see that image, but when I try to display it in frontend, I'm not that lucky.
Here is my function on backend to get image.
async getOneImage (req,res){
try{
const getOneImage = await CaseImage.findOne({ where: {CaseId: req.params.CaseId, id: req.params.id}});
if (getOneImage == null) {
res.status(400).send({ message: 'Prípad so zadaným ID sa nenašiel.' });
}
res.send(getOneImage);
}
catch (err) {
console.log(err);
res.status(400).send({ message: 'Nepodarilo sa načítať fotografie, skúste to neskôr.'});
}
},
Maybe should I change that response to binary or? I don't understand this topic cleary as you can see.
Thank you all for help and sorry if question is not correctly formated or named.
Ok so I tried, now I have request to node server but I get response 404 cannot get... so I'm assuming that problem is somewhere in my express settings...
this.imageSrc = http://localhost:3000/${data.path}.png
this is full url.. but response is 404.
http://localhost:3000/static/uploads/70e13f7cd5e6a3d0a0d0bc252d62fa31.png
edit.
So, this is my front-end.. You can see that I'm sending response to correct path.
frontend request
Here you can see how my backend setting of express looks like.
Express
And here is response that I'm getting when I send request to backend.
Response
But I'm still not able to see image in vue. When I check I see only blank space and in console is this reply:
"GET http://localhost:3000/static/uploads/70e13f7cd5e6a3d0a0d0bc252d62fa31.png 404 (Not Found)"
And in network tab is this.
Network tab
If you have correct paths to the images in your database you simply render them with an tag. Make sure the path to the file is complete, or relative to your static assets folder.
In your case the path seems to be some mix of static/uploads/hash and the filename problem.png.
This means the full url to the file is most likely something like:
domain.com/static/uploads//.png. The domain.com part will most likely be localhost: if you are working locally. On a production server this will be your domain you are hosting your app on.
PS. your second image is a full file path on your system, this wont be visible on a server.
So you have this static folder.
If you are not already serving this static folder with express, see this explanation on how to serve a static folder.
Once you fetch your image in the frontend you will have an image object something like this:
{
"id": 1,
"fileName": "problem.png",
"mimeType". "image/png",
"caseId: 2,
"path": "static/uploads/abcdefg.......png"
}
Your img tag in your html file should look as follows.
<img src="http://localhost:{PORT_OF_EXPRESS_SERVER}/static/uploads/abcdefg.........png"/>
Because you're using vue.js here is an example with axios.
MyComponent.js
import axios from 'axios';
export default {
data: () => {
return {
imageUrl: ''
}
},
mounted(): async () => {
// this route here must match what you defined in your backend
const { data } = await axios.get('/image/2/5')
console.log(data);
/** {
"id": 1,
"fileName": "problem.png",
"mimeType". "image/png",
"caseId: 2,
"path": "static/uploads/abcdefg.......png"
} **/
// now we set the imageUrl, assuming your express port is 1337
this.imageUrl = `http://localhost:1337/${data.path}`;
}
}
MyComponent.html
<template>
<div id="my-component">
<img :src="imageUrl"/>
</div>
</template>
<script src="./MyComponent.js"></script>

Server configuration for Vue.js History Mode with Vercel?

I set up a very basic Vue.js app essentially using these steps. When I added the router to this project, it asked whether I wanted to use History Mode and I said yes.
Now I am trying to implement the corresponding server configuration changes aka "add[ing] a simple catch-all fallback route to [the] server" but I'm not sure how to do this since I'm using Vercel for my deployments and from my understanding it's managing the server for me.
It seems like I'm able to do some configuration in Vercel, and I'm thinking maybe I need to configure a redirect like in their firebase.json example? If so, would my vercel.json just look like this?
{
"redirects": [
{ "source": "**", "destination": "/index.html" }
]
}
As per Vercel's vercel.json routes upgrade guide, SPA Fallback section, use this on your vercel.json file:
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}
In my case I'm also using Vercel Serverless functions, so I also need rewrites for the /api routes, and here the order is important, it must be done this way:
{
"rewrites": [
{ "source": "/api/(.*)", "destination": "/api" },
{ "source": "/(.*)", "destination": "/index.html" }
]
}
Generally, Vercel automatically detects your configuration and sets it up so that all traffic points at your index.html file. That's kind of their big selling point.
If you want more explicit control, you could use the configuration shown in the Caveat section of the Vue docs you first linked to. Just create a simple component that redirects to the homepage and point * to it.
import NotFound from '../components/NotFound.vue'
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '*', component: NotFound }
]
})
export default {
name: 'NotFound',
template: `<div></div>`,
mounted() {
this.$router.push({ path: '/' })
}
}
You are right, Vercel manages the server for you and you can configure vercel through a vercel.json file. In that vercel.json file you can define rewrite rules as you already assumed. The correct format for this is shown here in the docs of vercel.
Since you want to add a match all rule which directs to the base of your path, adding the following to your vercel.json should work:
{
"rewrites": [{ "source": "/:path*", "destination": "/index.html" }]
}
Explanatory extras:
The :path basically symbolizes a placeholder and the * makes sure it doesn't just match one subpath deep but everything that follows after the initial slash.
For example without the * after /:path you would match domain.xyz/foo but not domain.xyz/foo/bar.
Furthermore since it's a named placeholder you can reuse the matched path for the destination like so "destination": "/index.html/:path".
Which shouldn't be necessary for a frontend application like vue which uses the route inside the browser, but could be helpful for serverless functions.

How can I redirect my homepage to a random url through firebase hosting?

I am trying to redirect my homepage with 302 redirect using firebase hosting.
"redirects" :[{
"source": "/",
"destination": "what do i put here?",
"type": 302
}
]
In my public folder, I have the index.html, 404.html, and a folder full of files.
I would like for my homepage to randomly redirect to one of those files.
I know you can redirect in the index.html with location.href/assign/replace, but I have to do it through 302 redirect.
Thanks.
A possible alternative solution, involving Cloud Functions:
In firebase.json
"hosting": {
"rewrites": [
{
"source": "**",
"function": "randomRedirect"
}
]
}
In index.ts of your functions (assuming TypeScript):
export const randomRedirect = functions.https.onRequest((_, res: functions.Response) => {
res.redirect(302, 'your desired URL');
});
Edit: You need to remove your index.html file for the URL to change in the address bar.

React Router with a base path

I would like to add "/app" as my base path for all routes in react routes. So I am trying -
.... more routes
I am unable to make webpack dev server serve pages with URL localhost:8080/app. It gives me a "Cannot get /app" error. If I try localhost:8080/ - it gives me an error that it cannot match a route with "/".
What should be a basic webpack dev server configuration for this scenario?
The Webpack historyApiFallback config option is what you're looking for. Just set that to true and all requests that don't route to an asset will be rewritten to /. You can also pass in an object with custom rewrites:
historyApiFallback: {
rewrites: [
{ from: /^\/$/, to: '/views/landing.html' },
{ from: /^\/subpage/, to: '/views/subpage.html' },
{ from: /./, to: '/views/404.html' }
]
}
(Example taken from the documentation page linked above.)