Use remote and local images together with next/image - next.js

I am trying to use next/image to load local images as well as remote images. I have my local images in public/assets/images and remote images in AWS S3. I want to use a placeholder image (from local) before uploading the image, and then after the upload, replace it with the remote image.
I have added domains in my next.config.js:
const withPlugins = require('next-compose-plugins')
const nextTranslate = require('next-translate')
const nextConfig = {
...
images: {
domains: ['xxx.amazonaws.com'],
},
...
}
module.exports = withPlugins([nextTranslate], nextConfig)
But still, it proxies it with localhost and returns The requested resource isn't a valid image.
I tried adding path and loader along with domains in the config, but then it loads all the images from the given path, be it remote or local.
I can use the img tag for it but I wish to use next/image for image optimization. Is it possible?

I just ran into this problem and this is how I solved it. In your project's next.config.js file, add the list of domains where your site may be pulling images from. This would include localhost, the domain your site is on when deployed, and an external site. Then set the loader to custom.
// next.config.js
module.exports = {
images: {
domains: ['localhost', 'yourdomain.com', 'externaldomain.com'],
loader: 'custom'
}
}
Then in your code, for each image make sure you set the loader attribute and the correct src. Then for your local images set up your custom loader this way.
<Image loader={({src}) => src} src="/logo.png" layout="fill" />
Thank you to Hughes' above comment and the issue they linked for helping me figure this out.

Related

How can I get NextJs to serve a localised page?

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.

Images upload in React ,Nodejs changing from localhost to production in deployment

In dev mode i stored some photos and i get them buy using img tag with image link as src.
also , the api request from server using server url.
how should i make react use the correct url while using in deployment site and not "localhost"
//api
const url = "http://localhost:5000"
const exampleRouter= axios.create({
baseURL: `${url}/recipes/public`,
});
//In React components - img work fine
<img src={http://localhost:5000/users/${user._id}/avatar`} alt"avatr">
its worked perfectly in localhost, now i should deploy to heroku but i dont know how to treat this links ( i have tame many in my project)
I am using in React as FE and Node as BE with (using Express libary)
If it is frontend code
const l = window.location;
const url=`${l.protocol}//${l.host}:${l.port}`;
should do the trick.
Also, relative paths are a thing.

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.

Error generating next.js images path in export

I'm starting my studies in Next.js and managed to develop a relatively simple website, my problems started when I did a next export to make the website available on my client's hosting.
The problem is with the image paths. My settings are these:
File next.config.js
module.exports = ({
basePath: '/sitenext'
}
My image
<Image
src="/assets/images/logo.webp"
alt="Logo"
width={96}
height={116}
/>
The path of the image generated in HTML is this
/_next/image?url=%2Fassets%2Fimages%2Flogo.webp&w=384&q=75
After configuring basePath, works perfectly, only images that have not loaded correctly.
I also tried the root of the host and was also unsuccessful.
Locally everything works perfectly in both dev and start mode.
Thanks a lot for the help

How do I use CSS and JS files within a HTML file being sent with Express?

var express = require('express');
var app = express();
app.get('/', function(req, res) {
res.sendFile('main.html', { root : __dirname})
});
app.listen(9000, function(){
console.log('Listening on port 9000');
});
This current block of code works fine. Express is required and assigned to the variable app.
A HTML file is then sent (from the same directory) using res.sendFile as part of the app.get method.
Within the HTML file I am referencing a css file in the same directory, yet nothing is happening.
<link rel='stylesheet' type='text/css' href='mainstyle.css'>
How am I able to send the CSS file to the browser for use? res.sendFile does not work.
Thanks.
You need to define a static files directory. Create a folder called public and then include this line:
app.use(express.static('public'));
Don't include public in the file path when you include the css file though. All of your static files can go in that folder. Or, better still, create sub-folders for styles, images, fonts etc.
You can read more about it here: https://expressjs.com/en/starter/static-files.html
I think the problem you're having is that you're trying to create a web application from scratch using Express without any of the surrounding functionality. Your app sends a file when you navigate to the URL. It does not listen for specific requests for files and respond to them, it does not handle missing files, server errors etc.
You could do all that from scratch but in fact Express have created an application generator which creates a skeleton app for you with the web server, public folder, routes etc. It's called Express Generator and you can find it here: https://expressjs.com/en/starter/generator.html
That's a brilliant starting point for an MVC application. You get the package.json file for additional node modules, a template engine called Jade (although I prefer Hogan) for dynamic content and once it's created your app, you can fire it up by typing "npm start" in a console window.
try this
var express = require('express');
var app = express();
app.get('/', function(req, res) {
if(req.url == "/" || req.url == "/main.html"){
res.sendFile('/main.html', { root : __dirname})
}else if(req.url == "/mainstyle.css"){
res.sendFile('mainstyle.css', { root : __dirname})
}
});
app.listen(9000, function(){
console.log('Listening on port 9000');
});
I'm now aware of what was going wrong.
From the instance I started, I was experimenting with different code. The browser than created cache based on the incorrect code my server was providing, so no matter what I changed, the browser was reffering to it's cache to load, in this case, erroneous code.
For everyone who may be experiancing with similar issues when entering the correct code, clear cache history or use a incognito/private browser for developing.

Resources