How can I get NextJs to serve a localised page? - next.js

I need to export a static site to AWS S3 from a nextjs project. In order to handle next export I don't have the possibility to use normal internationalisation.
So what I did is to create my blog in English and create a folder /fr/ which contains the same pages translated. It's not a big deal, since it's a presentation website I have 5 pages, and the blog will be in en (not translated).
Currently nextjs is properly detecting the user language, and is sending back to the /fr/ path BUT it's reading from the index instead of reading from /fr/
So my current page is kept in en.
Is there a way to ask nextjs to read from the folder /fr ?
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
i18n: {
locales: ['en', 'fr'],
defaultLocale: 'en',
},
trailingSlash: true,
}
module.exports = nextConfig
Thanks

Some guidance for anyone having the same issue trying to build a static website in multiple languages, for very simple projects. Basically I ended up creating a folder /de/ and translate my pages there, and add a button to send users to the correct site.
It's working well because I have under 10 pages.

Even though NextJS is using /fr/ in the URL it is not using language in pages structure to locate the correct page.
If you want to continue with your approach you can use useRouter from NextJS in your pages which gives you access to router and from router you can get the active locale (see https://nextjs.org/docs/advanced-features/i18n-routing#accessing-the-locale-information). Then you can return correct content for given locale.

Related

nextjs i18n: move position of language code in url

We are working on a nextjs app with i18n. Now nextjs adds the language code in url automatically like /{language-code}/subroute/my-page. But we need it to be like /subroute/{language-code}/my-page. Is it possible through some configuration?
I checked basePath at https://nextjs.org/docs/api-reference/next.config.js/basepath, but it adds a prefix to ALL pages in the app. We just need some pages.
Also there is a so-called middleware to add custom routing rules: https://nextjs.org/docs/advanced-features/middleware. Is it possible to use it to need our needs?

Next JS nextjs rewrites not working as intended

I am proxying part of my site to a 'new' nextjs page, as such all my assets, images etc... are messing up because the pathing is wrong.
So, I used "assetPrefix" for the css/js files, BUT all my images and api's are wrong, so I am trying to do a rewrite and its not working...
Is there a way to have next be able to ignore the host (that is proxing) and just use its own domain.. for instance, all the assets are: https://preview.mysite.com (current site), but I want it to use its "real domain" -- https://previewnext.mysite.com
async rewrites() {
return [
{
source: 'https://preview.mysite.com/_next/image*',
destination: 'https://previewnext.mysite.com/_next/image*'
},
basically, if the path is: https://preview.mysite.com/_next/image?, which is my current domain that proxies the nextjs site, SO I need the nextjs site to actually rewrite those image assets to: https://previewnext.mysite.com/_next/image*
Seems a huge limitation to not be able to use absolute paths for rewrites.

How do I put a nextjs app in maintenance mode (using Vercel)

I've just released my nextjs app to production using Vercel.
I'm loving the whole experience except for one tiny part: I would have loved to be able to put my app in maintenance mode, but this option does not seem available on Vercel.
My question is: Has anyone achieved this before and could share some details here?
I'm guessing it could be done at 2 levels:
Modifying my app so that if an environment variable (i.e MAINTENANCE_MODE=true) is detected, every page redirects to a maintenance screen. However, this is not ideal, because adding an environment variable on Vercel requires a deployment for it to be taken into account.
Having a simple per-project toggle to enable/disable maintenance mode from Vercel. That would be mind-blowing.
"Maintenance Mode" can be achieved with an Environment Variable and redirects property in your next.config.js (requires Next.js 9.5.0 or newer).
module.exports = {
redirects() {
return [
process.env.MAINTENANCE_MODE === "1"
? { source: "/((?!maintenance).*)", destination: "/maintenance.html", permanent: false }
: null,
].filter(Boolean);
}
};
This adds a wildcard route that matches incoming requests and then issues a temporary redirect the /maintenance.html location.
Note that you cannot make changes to a deployment (config or environment variables) without deploying again.
Old Answer
If you're not using Next.js or using an old version of Next.js, "Maintenance Mode" can be achieved with the redirects property in vercel.json.
{
"redirects": [
{ "source": "/((?!maintenance).*)", "destination": "/maintenance.html", "permanent": false }
]
}
A different solution I am currently using would be to create a separate maintenance page and then conditionally intercept the rendering of the actual component based on an environment variable.
I achieve this by adjusting the _app.js code to:
function MyApp({ Component, pageProps }) {
if (process.env.NEXT_PUBLIC_MAINTENANCE_MODE === 'false') {
return <Component {...pageProps} />
} else {
return <Maintenance />
}
Note that as mentioned in earlier answers, this relies on the Vercel env variables, per their website: "A new Deployment is required for your changes to take effect."
To add on to comment by #ptrkcsk, if you are going the route of putting a maintenance page in pages directory and are rendering images with the <Image> component from next/image you will also want to include your static folder to the redirects regex.
This is the source pattern that is working for me: /((?!maintenance)(?!_next)(?!static).*)

How to implement a sitemap.xml file for a single page app using Firebase?

I was reading Google's guidelines about SEO and I found this.
Help Google find your content
The first step to getting your site on Google is to be sure that Google can find it. The best way to do that is to submit a sitemap. A sitemap is a file on your site that tells search engines about new or changed pages on your site. Learn more about how to build and submit a sitemap.
Obs.: My web app is an ecommerce/blog in which I have a shop that I have products to sell and I have a blogging section where I create and post content about those products.
So, each product has a product page, and each blog post has a blogPost page.
Then I went looking for some examples of Sitemaps from websites like mine that have good SEO ranking.
And I've found this good example:
robots.txt
User-Agent: *
Disallow: ... // SOME ROUTES
Sitemap: https://www.website.com/sitemap.xml
I.E: Apparently the crawler robot finds the Sitemap location from the robots.txt file.
And I've also found out that they keep separate sitemap files for blogPost and product pages.
sitemap.xml
<sitemapindex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/siteindex.xsd">
<sitemap>
<loc>https://www.website.com/blogPosts-sitemap.xml</loc> // FOR POSTS
<lastmod>2019-09-10T05:00:14+00:00</lastmod>
</sitemap>
<sitemap>
<loc>https://www.website.com/products-sitemap.xml</loc> // FOR PRODUCTS
<lastmod>2019-09-10T05:00:14+00:00</lastmod>
</sitemap>
</sitemapindex>
blogPosts-sitemap.xml
// HUGE LIST WITH AN <url> FOR EACH BLOGPOST URL
<url>
<loc>
https://www.website.com/blog/some-blog-post-slug
</loc>
<lastmod>2019-09-03T18:11:56.873+00:00</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
products-sitemap.xml
// HUGE LIST WITH AN <url> FOR EACH PRODUCT URL
<url>
<loc>
https://www.website.com/gp/some-product-slug
</loc>
<lastmod>2019-09-08T07:00:16+00:00</lastmod>
<changefreq>yearly</changefreq>
<priority>0.3</priority>
</url>
QUESTION
How can I keep updated Sitemap files like that if my web app is a Single Page App with client site routing?
Since I'm using Firebase as my hosting, what I've thought about doing is:
OPTION #1 - Keep sitemap.xml in Firebase Hosting
From this question Upload single file to firebase hosting via CLI or other without deleting existing ones?
Frank van Puffelen says:
Update (December 2018): Firebase Hosting now has a REST API. While this still doesn't officially allow you to deploy a single file, you can use it creatively to get what you want. See my Gist here: https://gist.github.com/puf/e00c34dd82b35c56e91adbc3a9b1c412
I could use his Gist to update the sitemap.xml file and run this script once a day, or whenever I want. This would work for my current project, but it would not work for a project with a higher change frequency of dynamic pages, like a news portal or market place, for example.
OPTION #2 - Keep sitemap.xml in Firebase Storage
Keep the sitemap files in my Storage bucket and update it as frequently as I need via a admin script or a cloud scheduled function.
Set a rewrite in my firebase.json and specify a function to respond and serve the sitemap files from the bucket, when requested.
firebase.json
"hosting": {
// ...
// Add the "rewrites" attribute within "hosting"
"rewrites": [ {
"source": "/sitemap.xml",
"function": "serveSitemapFromStorageBucket"
} ]
}
FINAL QUESTION
I'm leaning towards OPTION #2, I want to know if it will work for this specific purpose or if I'm missing something out.
I ended up creating a cloud function to build the sitemap file on-demand.
firebase.json
"rewrites": [
{
"source": "/sitemap.xml",
"function": "buildSitemap"
},
]
buildSitemap.js (this is a cloud function)
import * as admin from 'firebase-admin';
async function buildSitemap(req,res) {
// Use firebase-admin to gather necessary data
// Build the sitemap file string
// and send it back
res.set('Content-Type', 'text/xml');
res.status(200).send(SITEMAP_STRING);
return;
}
export default buildSitemap;
Remove src/sitemap.xml from angular.json
"assets": [
"src/assets",
"src/favicon.ico",
"src/manifest.json",
"src/robots.txt"
],

How do I deploy a VueJS project for production which is using the history mode for routing?

I have created a vueJS website and I have used the history mode for routing in order to get rid of the # in the URL which shows in the default has mode routing. However when I deploy my project to the server after
npm run build
it runs fine but when I reload any page or type the url in the browser manual i get a 404 error instead.
I have used the history mode for routing. I am using firebase for the backend. I read the documentation on how to fix this however I did not quite understand it.
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
mode : 'history',
routes : [
{
path : '/',
name : 'dashboard',
component : 'Dahsboard',
}
]
})
I don't have enough reputation to answer in the comment section under your question, so i provide an answer here.
You can find the code that tells the web server to serve the index.html file for every routing request here. Just create a .htaccess file and upload it to your server.
In your example above you also need to import your Dahsboard-Component if you are using single file components.

Resources