How do I use an image from an external domain in Next.js? - next.js

I'm trying to use the <Image> component in a Next.js project that references an external domain. I'm just working locally.
I'm instructed to add images.domains to my next.config.js file but that doesn't seem to work.
https://nextjs.org/docs/messages/next-image-unconfigured-host
next.config.js
module.exports = {
images: {
domains: ['placehold.it'],
},
webpack: (config) => {
config.module.rules.push({
test: /\.svg$/,
use: ['#svgr/webpack'],
});
return config;
},
};
My image:
<Image
width={400}
height={300}
src="http://placehold.it/400x300"
/>
Am I missing something?

You have to set a loader function.

From a quick view of the code, a domain seems to be correctly specified, but the image source simply has the domain + image size.
Does the stored image actually have a file name that needs to be included?
Obviously, if the images are stored just tagged by size, it's possible that a missing file type (e.g. jpg) is required.
If an image placeholder is appearing on the page, right click to inspect the element or right click to copy the image address and paste it somewhere to inspect the entire path and check to see if it makes sense.
A loader is required if using a service such as Cloudinary. Use of a loader complicates (prevents?) using local images but I don't know how it might impact simply getting remote images.

Related

Why next.js does not tell me which Image lacks src property?

Next.js is awesome. But it has bugs that drive developers crazy.
I'm creating a website and I have used next/image like in 25 places.
And now I get this error:
Error: Image is missing required "src" property. Make sure you pass "src" in props to the `next/image` component. Received: {}
at Image (webpack-internal:///../../site/node_modules/next/dist/client/image.js:157:19)
at renderWithHooks (/site/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5471:16)
at renderIndeterminateComponent (/site/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5544:15)
at renderElement (/site/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5759:7)
at renderNodeDestructive (/site/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5898:11)
at renderNode (/site/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6030:12)
at renderHostElement (/site/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5456:3)
at renderElement (/site/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5765:5)
at renderNodeDestructive (/site/node_modules/react-dom/cjs/react-dom-server.browser.development.js:5898:11)
at renderNode (/site/node_modules/react-dom/cjs/react-dom-server.browser.development.js:6030:12)
error - ../../site/node_modules/next/dist/client/image.js (159:18) # Image
It literally does not tell me anything about my source code.
How am I supposed to debug this error?
Can you share your code. probably you did not accept the next/image format. Just add src like that:
<Image
loader={myLoader}
src="me.png"
alt="Picture of the author"
width={500}
height={500}
/>
Try to delete your node_modules folder and then, install packages with npm i, I think there would be an issue that u have don`t passed the src props in any image tag, try to debug the src props that should be wrapped in src = {}

Loading local file inside an iframe in Electron

I've tried different approaches but all are problematic.
So first of all I was using webview, but as per electron documentation, this tag is undergoing major architectural changes and it's recommended to use iframe or other alternatives. Furthermore, the webview tag gives me a warning while used alongside VueJS that the component is not registered. I understand this component doesn't exist within HTML standards and is something specific to electron, so I am not sure how to tell Vue to ignore or recognize it in the use case of an electron app.
Coming to the iframe problem, approach one of loading the file directly via src, gives me the obvious error Not allowed to load local resource:. Turning off webSecurity though allows the file to load but I read it's not recommended to turn it off. I am not sure if there are specific use case where it's safe to turn it off or shouldn't be at all.
I decided to try via file protocol as I already have it in place. The protocol code:
protocol.registerFileProtocol('downloads', (request, callback) => {
const url = request.url.substring('downloads:///'.length)
const location = path.normalize(paths.downloads(url))
callback({ path: location })
})
Though when I load the file this way, the renderer process crash without errors. Is there something in addition to the above which would help loading local files via iframe?
Edit 1
My use case is the following: I have a typical entry point to an index.html which contains code for a VueJS app.
if (app.isPackaged) {
window.loadFile(join(__dirname, '../renderer/index.html'))
} else {
// 🚧 Use ['ENV_NAME'] avoid vite:define plugin
const url = `http://${process.env['VITE_DEV_SERVER_HOST']}:${process.env['VITE_DEV_SERVER_PORT']}`
window.loadURL(url)
window.webContents.openDevTools()
}
Inside that VueJS app, I require to list html files from a directory. I am able to achieve so via webview but I have tried to move away from it for the reason mentioned above. I tried using iframe but encountered issues as well. If there's a setting that doesn't turn off all security and allows me to load the file via iframe, that would be ideal.
This is kind of the reverse of this question where they're using an iframe, running into the "not allowed to load local resource" and being told to use a <webview> instead.
The <webview> docs list BrowserView as another alternative which is what I would recommend here. That should be much easier to work with than an iframe.
const { app, BrowserView, BrowserWindow } = require('electron')
app.whenReady().then(() => {
const win = new BrowserWindow()
const view = new BrowserView()
win.setBrowserView(view)
view.setBounds({ x: 0, y: 0, width: 300, height: 300 })
view.webContents.loadFile('<yourFile>')
})
Even though it is not recommended to use webview tag, I decided to go forward as it's the only thing that works for me. The only issue then was this error where Vue does not recognize the tag. To work around that error/warning, I had to update my vite.js config:
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag === 'webview'
}
}
}),
// ...

Nextjs Image component complaining that the host is not added to config, but it is

I have a weeeeeeird issue with Nextjs, I have it connected to a cms (storyblok) and all images that I use come from that place. All images work just fine, but now I added a few new ones and I keep getting the error that the host is not configured, but it is!
Error:
Error: Invalid src prop (https://a.storyblok.com/f/130657/88x88/f37f10e611/giantstitanslogo.png) on `next/image`, hostname "a.storyblok.com" is not configured under images in your `next.config.js`
See more info: https://nextjs.org/docs/messages/next-image-unconfigured-host
Component, logoImg.filename is the src url:
<Image
src={logoImg.filename}
alt={logoImg.alt}
width={logoImgDimensions.width}
height={logoImgDimensions.height}
layout="responsive"
/>
And the config:
module.exports = {
images: {
domains: ["a.storyblok.com"],
},
experimental: { esmExternals: true },
};
Also if I do the following:
Comment out the Image component and save
Refresh
Error is gone page loads
Now uncomment the Image component and save (without refresh)
The images show up just fine!
Refresh -> error again
I accidently found the answer here: https://github.com/vercel/next.js/discussions/18311#discussioncomment-113194
For whatever reason my Image component was imported from "next/Image" not "next/image" image with small "i", once I changed the import to "next/image" it worked just fine.

Angular2 router with param reload page change get CSS file directory

Normally if I click link on home link to detail link, like <a routerLink="/detail/{{record.TA001}}">,it work well and css file got very well.
As only I refresh this detail page, like localhost:3000/detail/0006
it got data ok, but get CSS file change the directory to the detail instead root directory, could not get the CSS file. My detail component is in app/content directory.
My index.html and CSS file in project root directory.
router :
const appRoutes: Routes = [
{
path: 'contact',
component: Contactcomponent
},
{
path: 'detail/:id',
component: Detailcomponent
},
{ path: '',
component: Contentcomponent
}
My project directory is like this:
i have known how to resolve this problem ,just router directive /detail/0005 change /0005, it woke fine . i think it was if router for root so you just can use one level just fine .it could not use two level approch , if u router not for root ,it can use it .
If you want to use relative path instead of calculating every time the absolute one (with ../ ../../ etc.) you should use moduleID property in your component declaration as explained here.
Check If u include base href="/" in index.html before including css/stylesheet

Phonegap: InAppBrowser insertCSS file

I'm trying to create an app that loads a website and then adds some custom CSS to adjust it to a mobile device.
I'm using window.open to load the page successfully, and I have a callback on loadstop where I'm calling browser.insertCSS, this is where the problem is.
If I do something like this:
browser.insertCSS({code:"body{background-color:red;}");
The style is applied correctly. However if I do this:
browser.insertCSS({file:"mobile-style.css");
And add the same CSS to the file, it doesn't get loaded
I have tried different paths (putting the file in the www folder, in the css folder, in the same folder as the JS file, and referencing it with "./mobile-style.css", "mobile-style.css", "/www/mobile-style.css", "/mobile-style.css" but none of them seem to load the file correctly.
I saw another post What should file paths fed to insertCSS() be relative to? where this same question was asked, but there is no accepted answer (I have tried the suggestion there and it doesn't work).
Any help would be greatly appreciated.
Thanks
Will
you have to wait until your inAppBrowser page loading finishes.
You must add an event listener:
var inApp = window.open('mypage.html', '_blank', 'location=no');
inApp.addEventListener('loadstop', function(){
inApp.insertCSS({
file: 'inAppStyle.css'
},onSuccess);
});
EDITED
Use this path for your android projects file:///android_asset/{your folder}
INFO: https://github.com/apache/cordova-plugin-file/blob/master/doc/index.md#android-file-system-layout
I couldn't find the right local path. Instead, I just uploaded the css file to the web and provided a regular URL
file: 'http://mywebsite.com/path-if-needed/my.css'
Not ideal to have an external dependency, but not a big deal since InAppBrowser itself requires internet access.
I probably know why it won't work, it is because your path isn't right, this css file should not put in www folder, neither the cordova project folder, u should put it into the server, for example, if ur browser is to visit http://192.168.1.1/admin, then the cordova only fetch this file when the browser is under the 192.168.1.1/admin, it fetch the file under the server directory.I don't know if u use any debug tool , if u use one, it's easy to find out what went wrong, ur console will log the error which path it fetch the css file and didn't get it.
If you want to add an external CSS file stored locally in the APP's sandbox and not around in the Internet, this is the only way, that is, you get the external file, you store it into a string variable, and then you insert such code into the Browser.
var inAppBrowserRef = cordova.InAppBrowser.open(url, "_blank", "location=no");
//when load stops call loadedCallbackFunction
inAppBrowserRef.addEventListener('loadstop', loadedCallbackFunction);
function loadedCallbackFunction() {
console.log("InAppBrowser Window loaded");
$.ajax({
type: "GET",
url: cordova.file.applicationDirectory + "www/css/myExternalCSS.css",
dataType: "text",
success: function (CSScode) {
inAppBrowserRef.insertCSS(
{ code: JScode},
function(){
console.log("CSS code Inserted Succesfully into inApp Browser Window");
});
},
error: function () {
console.error("Ajax Error");
}
});
}
You need the cordova-plugin-inappbrowser

Resources