Next.JS rewrite isn't happening - next.js

I hope this question is clear, I am somewhat at the end of my mental resources at the moment.
I have some Nginx rewrites happening in production, I need to reproduce this functionality in my nextjs app on the frontend.
So my rewrites rules look like the following
const rewrites = process.env.NODE_ENV === "development" ?
[{
source: '/ovp/userdevices',
destination: 'https://userdevices.backendservices.dk'
},
{
source: '/ovp/userdevices/:path*',
destination: 'https://userdevices.backendservices.dk/:path*'
}
] : [];
and in my configuration
async rewrites() {
console.log("Rewrites called");
return rewrites;
},
I get the console log, and the array is what it is supposed to be. But my /ovp/userdevices urls never get rewritten, and so we are always running localhost:3000/ovp/userdevices.
I am supposing at the moment that the rewrites never happen because these are supposed to be done on the serverside and maybe everything is being rendered frontend but I don't know how to test this supposition.
My current config looks like
{
poweredByHeader: false,
target: 'serverless',
distDir: 'build',
basePath: '',
rewrites: [AsyncFunction: rewrites],
redirects: [AsyncFunction: redirects],
pageExtensions: [ 'route.js' ],
env: {
SUPPORTED_BROWSERS: 'chrome 84;chrome 83;edge 84;edge 83;firefox 79;firefox 78',
APP_VERSION: '0.0.1',
APP_NAME: 'some-app/app-self-service'
},
webpack: [Function: webpack]
}
Can anyone point me to a reason why the rewrites would not be happening?
On Edit: I'm not going to delete the question in that maybe someone will find a use for it, but I was wrong, it was being rewritten it's just the url it was going to was failing. I didn't figure out why because I found a simpler hack to solve my problem.

You can't use the name rewrites twice. Make next.config.js look like this:
module.exports = {
async rewrites() {
console.log("Rewrites called");
return process.env.NODE_ENV === "development"
? [
{
source: "/ovp/userdevices",
destination: "https://userdevices.backendservices.dk",
},
{
source: "/ovp/userdevices/:path*",
destination: "https://userdevices.backendservices.dk/:path*",
},
]
: [];
},
};

Related

How to prevent direct access to pages url in nextjs when used rewrites?

My problem is : I have pages/blog.js file in my project. I did localized urls like down below in the next.config.js file.
i18n:{
locales:["tr","en"],
defaultLocale:"tr"
},
async rewrites(){
return [
{
"source":"/tr/makaleler",
"destination":"/blog",
"locale":false
},
{
"source":"/en/articles",
"destination":"/blog",
"locale":false
}
]
}
It works. But problems is ; I can still access with this localhost:3000/blog. I want to make it only accessible with localhost:3000/makaleler or localhost:3000/en/articles.
Is there any way to achieve this? I have read "nextjs" documentation bu couldn't find anything useful.
Essentially what you want is not possible, The reason is if you restrict access to localhost:3000/blog by any means, then your rewrites will stop working as well.
What you probably need is redirects from localhost:3000/blog to the desired locale for your users. You can leverage Accept-Language header for example:
async redirects() {
return [
{
source: '/blog',
has: [
{
type: 'header',
key: 'accept-language',
// header starts with tr
value: 'tr(.*)',
},
],
destination: '/tr/makaleler',
permanent: false,
},
{
source: '/blog',
has: [
{
type: 'header',
key: 'accept-language',
// header does not start with tr
value: '((?!tr$).*)',
},
],
destination: '/en/articles',
permanent: false,
},
]
}
You should use Next.js Middleware in version 12.2 if you want to implement complex redirect logic based on language (or anything). You can find a quick tutorial by Vercel in Youtube here: https://youtu.be/j7rPSS9Ovsw?t=296

How to configure path in NextJS

I have the following addresses /blog/post-1, /blog/post-2 and I want to rewrite all paths to /post-1, /post-2. I configure in the file next.config.js as follows
async rewrites() {
return [
{
source: '/:slug',
destination: '/blog/:slug',
},
]
}
However, the old path and the new path both work? What should I do?
You have them set up the wrong way around if you are trying to redirect from /blog/post-1 to /post-1/ and you need the path parameter.
From the docs https://nextjs.org/docs/api-reference/next.config.js/rewrites
module.exports = {
async rewrites() {
return [
{
source: '/blog/:path*',
destination: '/:path*', // The :path parameter is used here so will not be automatically passed in the query
},
]
},
}

How to rewrite homepage based on hostname

I'd like to show two different pages at '/' depending on the hostname (the value for req.hostname). This is because I have a subdomain xxx.mydomain.com that needs to show just one page at the root URL. The idea is to have a CNAME for the subdomain that points to the same server as www. I'm using next version 11.1.2 .
My homepage (/pages/index.js) uses getStaticProps to get data for the page with a revalidate interval of 2 seconds. The page on the production branch works great currently without any rewriting.
I tried using the rewrites option in next.config.js and was able to use this to rewrite all other routes, but rewriting with source: '/' did not do anything. If the source was any other page it worked perfectly. This is pretty much what the next.config.js file looked liken when I tried the rewrite:
const withFonts = require('next-fonts');
const withTM = require('next-transpile-modules')(['#cal-frontends/shared']);
require('dotenv').config({ path: '../../.env' });
module.exports = withTM(withFonts({
async rewrites() {
return [
{
source: '/', // this one still showed the homepage at '/'
destination: '/mission',
},
{
source: '/foo', // this one showed the contact page at '/foo'
destination: '/contact',
},
]
},
webpack(config, options) {
return config;
},
}));
I tried many strategies, including this kind of configuration in server.js
server.get('/',function(req,res){
console.log('trying to redirect', )
console.log('req.hostname', req.hostname)
if (req.hostname === 'mission.mydomain.com') {
console.log('this should show mission', )
return app.render(req, res, '/mission', {})
} else {
handle(req, res);
}
});
This unfortunately did not seem to override the static caching that happens with getStaticProps – you will only see the correct page for the hostname if you load and then reload after it revalidates.
Is there an elegant way to do this?

Exposing Storybook via NextJS route

I have a NextJS app and am using Storybook to develop my components.
After looking through all the NextJS routing documentation, I can't find a way to route to my storybook from within NextJS. Only access pages within the /pages directory.
What I would like to do it to have my StoryBook available at /styleguide from within my Next app thought all environments.
Is someone able to help?
Short answer: No, you can not do that.
But you can always redirect the url /styleguide to another domain where Storybook is running, for example styleguide.example.com. Here, an example based on the official documentation:
// next.config.js
module.exports = {
async redirects() {
return [
{
source: '/styleguide',
destination: 'https://styleguide.example.com',
permanent: true,
},
]
},
}
If your URL's would have any parameters for it's origin that you would want to append to the redirects destination, NextJS provides a feature to do just that.
// next.config.js
module.exports = {
async redirects() {
return [
{
source: '/styleguide/:pageId/:slug',
destination: 'https://styleguide.example.com/:pageId/:slug',
permanent: true,
},
]
},
}

Use regex on catch all route rewrites in next.js

I'm trying to implement pagination in my application by rewriting numbers in the path to the query var ?page. I got it to work more or less, but the string part of the path gets cut in half.
My next.config.js looks like this:
const withImages = require('next-images');
module.exports = withImages({
async rewrites() {
return [
{ source: '/categoria/:slug*(\\w{1,})', destination: '/category/:slug*' },
{ source: '/categoria/:slug*(\\w{1,})/:page(\\d{1,})', destination: '/category/:slug*/?page=:page' },
];
}
});
The route I'm working with is /category/[...slug].
I tried changing \\w{1,} to \\w+, [a-z-]{1,}, [a-z-]+ and all of them ended up giving the same result.

Resources