Next.js Image component with external dynamic source - image

I was working on my Next.js project and while running it locally html img tag worked okay.
While building, I got a warning, to change it to Image component from Next.js
So I did, but now I get a warning:
Error: Invalid src prop (https://image.ceneostatic.pl/data/products/10813131/i-dixit.jpg) on next/image, hostname "image.ceneostatic.pl" is not configured under images in your next.config.js
See more info: https://nextjs.org/docs/messages/next-image-unconfigured-host
I read in the documentation that solution is to add a domain to next.config.js.
But 2 problems occurs to me here:
Even if I specify a domain like this, it doesn't work
module.exports = {
images: {
domains: ['image.ceneostatic.pl'],
},
};
I have my project connected to MongoDB, where are stored links to the images. What's more, I want an user to pass a link, while creating a new entry. So I don't want to have hard-coded domains, as I don't know which img an user will use.
Is there a way to omit domains list or a walk-around to use tag?
Thanks!

You can use something called next Loader via the following code:
import Image from 'next/image'
const myLoader = ({ src, width, quality }) => {
return `https://image.ceneostatic.pl/data/products/{src}/i-dixit.jpg`
}
var photoID = 10813131
const MyImage = (props) => {
return (
<Image
loader={myLoader}
src=photoID
width={500}
height={500}
/>
)
}
Your next.config.js:
module.exports = {
images: {
loader: 'imgix',
path: 'https://image.ceneostatic.pl',
},
}
All documentation is linked here.

Related

Access to dynamic Images with vue and playframework

I use vue and Play!Framework for my project.
Fronted: Vue.js 2.6.12
Backend: Play!Framework with Scala (2.12.8)
I use following Code snippet to upload an image to my server (This is copied from here: https://www.playframework.com/documentation/2.8.x/ScalaFileUpload
def uploadImage = Action.async{ implicit request =>
request.body.asMultipartFormData.map{ pic =>
val file = pic.files
val userIdTemp = pic.asFormUrlEncoded("userId")
val userId = userIdTemp.head.toInt
val itemIdTemp = pic.asFormUrlEncoded("itemId")
val itemId = itemIdTemp.head.toInt
val contentType = file.head.contentType
val filename = Paths.get(file.head.filename).getFileName.toString().toLowerCase()
val fileSize = file.head.fileSize
print("content Type: "+contentType)
print("filename: "+filename)
print("filesize: "+fileSize)
file.head.ref.moveFileTo(Paths.get(s"...\\vui\\src\\assets\\"+filename).toFile, replace = true)
print("***********************uploadImage -3")
service.saveImage(userId,itemId, filename.toString()) map{ foundItems =>
Ok(Json.toJson(foundItems))
}
}.getOrElse(null) // change me
}
I upload the image to the server and save the url related to an item in my database. This works fine. I display the images in my fronted with following code snippet:
<b-carousel-slide :img-src="require('../../assets/'+img.imgUrl)" >
</b-carousel-slide>
When i try to upload an image which i have uploaded before it works fine, but if i try to upload an image for the first time i get following exception:
Error: Cannot find module './001.jpg'
webpackContextResolve .*$:70
webpackContext .*$:65
render FoodMenuItem.vue:1302
renderList VueJS
render FoodMenuItem.vue:1274
VueJS 14
createNewImages FoodMenuItem.vue:809
uploadImage FoodMenuItem.vue:802
promise callback*p$1.then vue-resource.esm.js:230
uploadImage FoodMenuItem.vue:799
onSelect FoodMenuItem.vue:720
VueJS 33
updateTarget transporter.js:145
updated transporter.js:98
VueJS 13
click FoodMenuItem.vue:1256
VueJS 3
vue.runtime.esm.js:1897
VueJS 17
createNewImages FoodMenuItem.vue:809
uploadImage FoodMenuItem.vue:802
then vue-resource.esm.js:230
uploadImage FoodMenuItem.vue:799
onSelect FoodMenuItem.vue:720
VueJS 33
updateTarget transporter.js:145
updated transporter.js:98
VueJS 13
click FoodMenuItem.vue:1256
VueJS 3
The images is uploaded and the url is saved in the database, but my frontend crashed. When i "complete" refresh my browser and try it again, evertything works fine. My guess is, i can not access to image with require who are not loaded?
Is there a way to display this images without refreshing the browser? Is that a normal way to handle images in a web application? Any help will help!
If u need more information to help, just ask me:)
Thank you!
I tried a lot of things and i followed this steps:
https://blog.lichter.io/posts/dynamic-images-vue-nuxt/
As i told you above, i am uploading my images at the moment to the assets folder in UI. If i am in dev mode i can upload new images and show them with following code:
<img :src="require(`../../assets/${img.imgUrl}`)" >
And this works now. But when i change in production mode with:
npm run build
sbt compile stage
sbt start
The Frontend App will be a static app in the folder public/ui/
and then i donĀ“t know the right relative path for the new images...
vue.config.js:
const path = require("path");
const webpack = require('webpack')
module.exports = {
outputDir: path.resolve(__dirname, "../public/ui"),
assetsDir: process.env.NODE_ENV === 'production' ? 'static':'',
devServer: {
public: 'localhost:8080',
headers: {
'Access-Control-Allow-Origin': '*',
}
},
configureWebpack: {
plugins: [
new webpack.DefinePlugin({
'process.conf': {
'RECAPTCHA_SITEKEY': JSON.stringify(process.env.RECAPTCHA_SITEKEY)
}
})
]
},
chainWebpack: config => {
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.transformAssetUrls = {
img: 'src',
image: 'xlink:href',
'b-avatar': 'src',
'b-img': 'src',
'b-img-lazy': ['src', 'blank-src'],
'b-card': 'img-src',
'b-card-img': 'src',
'b-card-img-lazy': ['src', 'blank-src'],
'b-carousel-slide': 'img-src',
'b-embed': 'src'
}
return options
})
}
}
In which folder do i have upload the images? How can i reach the new uploaded images in production mode?

Can I get FilePond to show previews of loaded local images?

I use FilePond to show previously uploaded images with the load functionality. The files are visible, however I don't get a preview (which I get when uploading a file).
Should it be possible to show previews for files through load?
files: [{
source: " . $profile->profileImage->id . ",
options: {
type: 'local',
}
}],
First you have to install and register File Poster and File Preview plugins and here is the example of how to register it in your code:
import * as FilePond from 'filepond';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import FilePondPluginFilePoster from 'filepond-plugin-file-poster';
FilePond.registerPlugin(
FilePondPluginImagePreview,
FilePondPluginFilePoster,
);
then You have to set the server.load property to your server endpoint and add a metadata property to your files object which is the link to your image on the server:
const pond = FilePond.create(document.querySelector('file'));
pond.server = {
url: '127.0.0.1:3000/',
process: 'upload-file',
revert: null,
// this is the property you should set in order to render your file using Poster plugin
load: 'get-file/',
restore: null,
fetch: null
};
pond.files = [
{
source: iconId,
options: {
type: 'local',
metadata: {
poster: '127.0.0.1:3000/images/test.jpeg'
}
}
}
];
the source property is the variable you want to send to your end point which in my case I wanted to send to /get-file/{imageDbId}.
In this case it does not matter what your endpoint in the load property returns but my guess is, we have to return a file object.

Specify the webpack "mainFields" on a case by case basis

Webpack has a resolve.mainFields configuration: https://webpack.js.org/configuration/resolve/#resolvemainfields
This allows control over what package.json field should be used as an entrypoint.
I have an app that pulls in dozens of different 3rd party packages. The use case is that I want to specify what field to use depending on the name of the package. Example:
For package foo use the main field in node_modules/foo/package.json
For package bar use the module field in node_modules/bar/package.json
Certain packages I'm relying on are not bundled in a correct manner, the code that the module field is pointing to does not follow these rules: https://github.com/dherman/defense-of-dot-js/blob/master/proposal.md This causes the app to break if I wholesale change the webpack configuration to:
resolve: {
mainFields: ['module']
}
The mainFields has to be set to main to currently get the app to work. This causes it to always pull in the CommonJS version of every dependency and miss out on treeshaking. Hoping to do something like this:
resolve: {
foo: {
mainFields: ['main']
},
bar: {
mainFields: ['module'],
}
Package foo gets bundled into my app via its main field and package bar gets bundled in via its module field. I realize the benefits of treeshaking with the bar package, and I don't break the app with foo package (has a module field that is not proper module syntax).
One way to achieve this would be instead of using resolve.mainFields you can make use of resolve.plugins option and write your own custom resolver see https://stackoverflow.com/a/29859165/6455628 because by using your custom resolver you can programmatically resolve different path for different modules
I am copy pasting the Ricardo Stuven's Answer here
Yes, it's possible. To avoid ambiguity and for easier implementation,
we'll use a prefix hash symbol as marker of your convention:
require("#./components/SettingsPanel");
Then add this to your configuration file (of course, you can refactor
it later):
var webpack = require('webpack');
var path = require('path');
var MyConventionResolver = {
apply: function(resolver) {
resolver.plugin('module', function(request, callback) {
if (request.request[0] === '#') {
var req = request.request.substr(1);
var obj = {
path: request.path,
request: req + '/' + path.basename(req) + '.js',
query: request.query,
directory: request.directory
};
this.doResolve(['file'], obj, callback);
}
else {
callback();
}
});
}
};
module.exports = {
resolve: {
plugins: [
MyConventionResolver
]
}
// ...
};
resolve.mainFields not work in my case, but resolve.aliasFields works.
More details in https://stackoverflow.com/a/71555568/7534433

How to debug an import binding name that is not found

I have a NativeScript application that I'm trying to add iBeacon support to using the iBeacon plugin. The application builds successfully and is synced to my phone (I'm using SideKick). When the app runs, it has a fatal javascript exception. The javascript error is reported at:
file:///app/tns_modules/tns-core-modules/ui/builder/builder.js:244:56: JS ERROR Error: Building UI from XML. #file:///app/app-root.xml:18:9
That line is where the page that attempts to access the iBeacon code is defined:
<Frame defaultPage="views/search/search-page"></Frame>
and the specific error is:
Importing binding name 'BeaconLocationOptions' is not found.
I'm assuming this occurs as part of the following import statement:
import {NativescriptIbeacon, BeaconCallback, BeaconLocationOptions, BeaconLocationOptionsIOSAuthType, BeaconLocationOptionsAndroidAuthType, BeaconRegion, Beacon } from 'nativescript-ibeacon';
The above import statement is what is documented as part of the iBeacon documentation.
There is a nativescript-ibeacon directory under node_modules in my project. The specific ios file seems to be there:
/Users/edscott/NativeScript/beacon-test/node_modules/nativescript-ibeacon/nativescript-ibeacon.ios.js
I'm not sure if it is a problem in my code or a problem with configuration - maybe something missing that stops the ibeacon files from being deployed properly to the device.
My code is in javascript, but I have installed the typescript plugin. It looks like this iBeacon plugin assumes the app is written in typescript.
I'm looking for help in determining what to try next.
FYI...I've tried pulling the source files out of the node_modules and incorporating them directly into my project. After resolving many issues with this approach, I eventually hit the same wall - a problem importing the code when running on the device.
Below is the code that is using the iBeacon plugin:
const observableModule = require("tns-core-modules/data/observable");
import {NativescriptIbeacon, BeaconCallback, BeaconLocationOptions, BeaconLocationOptionsIOSAuthType, BeaconLocationOptionsAndroidAuthType, BeaconRegion, Beacon } from 'nativescript-ibeacon';
function SearchViewModel() {
let callback = {
onBeaconManagerReady() {
// start ranging and/or monitoring only when the beacon manager is ready
this.nativescriptIbeacon.startRanging(this.region);
this.nativescriptIbeacon.startMonitoring(this.region);
},
didRangeBeaconsInRegion: function(region, beacons) {
console.log("didRangeBeaconsInRegion");
},
didFailRangingBeaconsInRegion: function(region, errorCode, errorDescription) {
console.log("didFailRangingBeaconsInRegion");
}
};
let options = {
iOSAuthorisationType: BeaconLocationOptionsIOSAuthType.Always,
androidAuthorisationType: BeaconLocationOptionsAndroidAuthType.Coarse,
androidAuthorisationDescription: "Location permission needed"
};
let nativescriptIbeacon = new NativescriptIbeacon(callback, options);
let region = new BeaconRegion("HelloID", "2f234454-cf6d-4a0f-adf2-f4911ba9ffa6");
const viewModel = observableModule.fromObject({
"beaconData": "not set yet",
"onTapStart": function() {
this.set("beaconData", "started");
console.log("tapped start");
if (!nativescriptIbeacon.isAuthorised()) {
console.log("NOT Authorised");
nativescriptIbeacon.requestAuthorization()
.then(() => {
console.log("Authorised by the user");
nativescriptIbeacon.bind();
}, (e) => {
console.log("Authorisation denied by the user");
})
} else {
console.log("Already authorised");
nativescriptIbeacon.bind();
}
},
"onTapStop": function() {
this.set("beaconData", "stopped");
console.log("tapped stop");
nativescriptIbeacon.stopRanging(region);
nativescriptIbeacon.stopMonitoring(region);
nativescriptIbeacon.unbind();
}
});
return viewModel;
}
module.exports = SearchViewModel;
I have created a playground for you here.
If you look into example, I am importing NativescriptIbeacon from the main folder and rest from the common folder.
P.S. This plugin has dependency on nativescript-permission
import { NativescriptIbeacon } from '../nativescript-ibeacon';
import {
BeaconRegion, Beacon, BeaconCallback,
BeaconLocationOptions, BeaconLocationOptionsIOSAuthType, BeaconLocationOptionsAndroidAuthType
} from "../nativescript-ibeacon/nativescript-ibeacon.common";
This answer solved my problem along with another modification. After splitting the import up I still had the same error. Then I read the following page about modules:
https://docs.nativescript.org/core-concepts/android-runtime/getting-started/modules
Based on this statement:
If the module identifier passed to require(moduleName) does not begin
with '/', '../', or './', then NativeScript will lookup the module
within the tns_modules folder
I assumed that maybe only require does the proper lookup into tns_modules.
I refactored the import to use require instead, and that worked. My changes are below. There may be a more efficient way to do this, but it worked for me.
const nsb = require("nativescript-ibeacon/nativescript-ibeacon.js");
const nsbc = require("nativescript-ibeacon/nativescript-ibeacon.common.js");
const NativescriptIbeacon = nsb.NativescriptIbeacon;
const BeaconCallback = nsbc.BeaconCallback;
const BeaconLocationOptions = nsbc.BeaconLocationOptions;
const BeaconLocationOptionsIOSAuthType = nsbc.BeaconLocationOptionsIOSAuthType;
const BeaconLocationOptionsAndroidAuthType = nsbc.BeaconLocationOptionsAndroidAuthType
const BeaconRegion = nsbc.BeaconRegion;
const Beacon = nsbc.Beacon;

Can we integrate kibana with kendo-ui?

I tried to integrated kibana with kendo-ui to view the visuals at the kibana dashboard.Is that possible to do like that?
yes.. but there is no official process provided by kibana #team.. I have done this using creating custom visualization plugin..
Plugin index.js
'use strict';
module.exports = function (kibana) {
return new kibana.Plugin({
uiExports: {
visTypes: ['plugins/kendo_vislib_vis_types/kendo_vislib_vis_types']
}
});
};
kendo_vislib_vis_types
define(function (require) {
const visTypes = require('ui/registry/vis_types');
visTypes.register(require('plugins/kendo_vislib_vis_types/line'));
visTypes.register(require('plugins/kendo_vislib_vis_types/bar'));
visTypes.register(require('plugins/kendo_vislib_vis_types/pie'));
visTypes.register(require('plugins/kendo_vislib_vis_types/metric'));
});
Remaining followed http://logz.io/blog/kibana-visualizations/
esResponse Data should be formatted in kendo required format using
$scope.$watch('esResponse', function (resp) {
if (resp) {
var currentState = $scope.vis.getState();
$scope.vis.setState(ktInterval.changeInterval(currentState));
$scope.kendoOptionGroup = [];
// console.log(tabifyAggResponse($scope.vis, resp));
$scope.resp = +moment();
$scope.processTableGroups(tabifyAggResponse($scope.vis, resp));
}
});
Note: CSS files injected with hardcoded way directly into src/ui/ui_app.jade, because though plugin means css images path should be in kibana understandable format which need modify manually in kendo.*.min.css.
kendo CSS files injecting to kibana
var files = [
bundleFile('commons.style.css'),
bundleFile('kendo/styles/kendo.default.min.css'),
bundleFile('kendo/styles/kendo.common.min.css'),
bundleFile('#{app.id}.style.css'),
bundleFile('custom.style.css'),
bundleFile('commons.bundle.js'),
bundleFile('#{app.id}.bundle.js')
];

Resources