Hello i have issue to get src url image with next/image, i already setup in next.config.js but still error. here my code
index.js
<Image src={'http://110.100.190.222:9790/images/'+item.article_image_path} alt="logo" width={300} height={100} />
next.config.js
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
optimizeFonts: true,
images: {
remotePatterns: [
{
protocol: 'http',
hostname: '110.100.190.222:9790',
},
],
minimumCacheTTL: 1500000,
},
}
module.exports = nextConfig
here still error
i try using this host https://freeimage.host/i/HIV7RRI works smooth, but with domain like that still error. that domain ip public is not my real domain ip public.
i found way but force,
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
optimizeFonts: true,
images: {
remotePatterns: [
{
protocol: 'http',
hostname: '**',
},
],
minimumCacheTTL: 1500000,
},
}
module.exports = nextConfig
Related
I write this code below in my next.config.js
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
images: {
remotePatterns: [
{
protocol: 'https',
hostname: [
'images.unsplash.com',
'hydeparkwinterwonderland.com',
'wembleypark.com']
},
]
}
}
module.exports = nextConfig
but it throw an error like this:
The value at .images.remotePatterns[0].hostname must be a string but it was an array.
See more info here: https://nextjs.org/docs/messages/invalid-next-config
Error: Invalid images.remotePatterns values:
{"protocol":"https","hostname":["images.unsplash.com","hydeparkwinterwonderland.com","wembleypark.com"]}
remotePatterns value must follow format { protocol: 'https', hostname: 'example.com', port: '', pathname: '/imgs/**' }.
See more info here: https://nextjs.org/docs/messages/invalid-images-config
looking for an answer, I'm a newbie please be patient with me
hostname only allows a single value, so you cannot pass an array of host names. Instead of that, you can have multiple items for host names in remotePatterns.
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'images.unsplash.com'
},
{
protocol: 'https',
hostname: 'hydeparkwinterwonderland.com'
},
{
protocol: 'https',
hostname: 'wembleypark.com'
},
]
}
}
Or less duplicated code with map
const hostnames = [
'images.unsplash.com',
'hydeparkwinterwonderland.com',
'wembleypark.com']
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
images: {
remotePatterns: hostnames.map(hostname => ({
protocol: 'https',
hostname
}))
}
}
So you are trying to configure multiple remote domains but nextjs doesn't allow you to specify hostname as an array (as the name stated it's hostname), so answer your original questions you need to tweak the code as below.
const nextConfig = {
reactStrictMode: true,
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'images.unsplash.com'
},
{
protocol: 'https',
hostname: 'hydeparkwinterwonderland.com'
},
{
protocol: 'https',
hostname: 'wembleypark.com'
},
]
}
}
Basically remotePatters accept an array of object and each object denote one pattern so you need to create multiple patterns for the different domain name.
I want to enable CORS for all sources and destinations from my app.
I am following this https://vercel.com/guides/how-to-enable-cors as my deployment of the Nextjs app is on Vercel.
Below is my next.config.js file.
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: false,
swcMinify: true,
eslint: {
ignoreDuringBuilds: true,
},
async headers() {
return [
{
source: '/',
headers: [
{ key: 'Access-Control-Allow-Credentials', value: 'true' },
{ key: 'Access-Control-Allow-Origin', value: '*' },
{
key: 'Access-Control-Allow-Methods',
value: 'GET,OPTIONS,PATCH,DELETE,POST,PUT',
},
{
key: 'Access-Control-Allow-Headers',
value:
'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version',
},
],
},
]
},
}
module.exports = nextConfig
The aim is to allow Access-Control-Allow-Origin: "*" for all the API calls from the app.
For a project I have the following url:
https://beterbijons.nl/belevingsapp/?name=Natuurleerpad
The website is made with NextJS, when I test this locally I had to add the following code:
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
env: {
BASE_URL: process.env.BASE_URL,
},
trailingSlash: true,
images: {
loader: 'akamai',
path: '',
},
async redirects() {
return [
{
source: '/belevingsapp/',
has: [
{
type: 'query',
key: 'name',
value: '(?<paramName>.*)'
},
],
destination: '/belevingsapp/natuurleerpad-schipperskerk',
permanent: true,
},
]
},
}
module.exports = nextConfig
my firebase.json looks like:
{
"hosting": {
"public": "out",
"target": "productie-frontend",
"ignore": [
".firebase/**",
".firebaserc",
"firebase.json",
"**/node_modules/**"
],
"redirects": [ {
"regex": "/belevingsapp/?name=(.*)",
"destination": "/belevingsapp/natuurleerpad-schipperskerk",
"type": 301
}
]
}
}
This works. Only when I publish it to firebase hosting do I get a 'page not found' page, does anyone have a solution for this? The given url with ? I can't adjust..
I switched my NextJS app to SWC (I removed Babel`s config, and enabled the emotion plugin).
Now, I see that build time has increased from 80 s to ~200 s.
Does anyone have a similar experience?
My next.config.js:
// #ts-check
const path = require('path')
const _ = require('lodash')
const withBundleAnalyzer = require('#next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
})
const withImages = require('next-optimized-images')
const withFonts = require('next-fonts')
const withTM = require('next-transpile-modules')([
'#xxx/helpers',
'#xxx/ui',
'#xxx/api',
])
console.log('basePath -', process.env.BASE_PATH)
console.log(`Fs cache ${process.env.ENABLE_FS_CACHE ? 'enabled' : 'disabled'}`)
/**
* Filters out keys with undefined value to be compliant with Next's env type definition
* #param {{ [key: string]: string | undefined }} envs
* #returns {{ [key: string]: string}}
*/
const getEnvs = (envs) => {
/** #type {{ [key: string]: string}} */
const result = {}
Object.entries(envs).forEach(([key, env]) => {
if (env) result[key] = env
})
return result
}
/**
* #type {import('next').NextConfig}
*/
const settings = {
env: getEnvs({
...
}),
trailingSlash: true,
poweredByHeader: false,
basePath: process.env.BASE_PATH,
baseUrl: process.env.BASE_URL,
assetPrefix: process.env.ASSET_PREFIX,
esModule: true,
handleImages: ['jpeg', 'png', 'webp', 'gif'],
// #ts-ignore fix images config to match next types. We need to extract images sizes from test setup
images: {
disableStaticImages: true,
domains: ['images.ctfassets.net'],
loader: 'custom',
},
eslint: {
ignoreDuringBuilds: true,
},
experimental: {
emotion: true,
},
swcMinify: true,
distDir: 'dist',
webpack: (config, { isServer }) => {
config.module.rules.push({
test: /\.svg$/,
use: [
{
loader: '#svgr/webpack',
options: {
svgoConfig: {
plugins: [
{
name: 'removeViewBox',
active: false,
},
{ name: 'cleanupIDs', active: false },
{ name: 'prefixIds', active: true },
],
},
},
},
'url-loader',
],
})
config.module.rules.push({
test: /\.mp4$/,
use: [
{
loader: 'file-loader',
options: {
publicPath: `${process.env.ASSET_PREFIX || ''}/_next/static/videos/`,
outputPath: `${config.isServer ? '../' : ''}static/videos/`,
name: '[name]-[hash].[ext]',
},
},
],
})
config.module.rules.push({
test: /\.json(.*?)\.data$/,
use: [
{
loader: 'file-loader',
options: {
publicPath: `${process.env.ASSET_PREFIX || ''}/_next/static/data/`,
outputPath: `${config.isServer ? '../' : ''}static/data/`,
name: '[name]-[hash].json',
},
},
],
})
if (!isServer) {
config.resolve.fallback.fs = false
config.resolve.fallback.path = false
config.resolve.fallback.crypto = false
config.resolve.fallback.readline = false
}
return config
},
}
const enhanceConfig = _.flow([withImages, withFonts, withBundleAnalyzer, withTM])
module.exports = enhanceConfig(settings)
I've added .scss styling to my site. The .scss files sit next to their .jsx components.
I reference the styles in .jsx like this:
import styles from './guest-card.component.scss'
...
<Card className={styles.card}>
Everything looks great when I run my local server webpack-dev-server --inline --progress --config build/webpack.cold.conf.js
When I build for distributing the app, such as Development machine or QA machine I run npm run build. This builds a dist folder with everything compiled.
When I view my site on a dev/qa server my styles are missing.
Looking in the dist folder I see a /static/css/app.css with my compiled styles. Great! The styles look correct.
My question: What do I do to include these /static/css/app.css in my production site? I tried adding a <link rel="stylesheet" ... to include it and im sure that would work but would give a 404 on my local machine.
Whats the correct way of having styles built
So my question is:
My question is - how do I get my app to reference this new app.css? If I add a
build.js
'use strict';
require('./check-versions')();
process.env.NODE_ENV = 'production';
const ora = require('ora');
const rm = require('rimraf');
const path = require('path');
const chalk = require('chalk');
const webpack = require('webpack');
const config = require('../config');
const webpackConfig = require('./webpack.prod.conf');
const spinner = ora('building...');
spinner.start();
rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
if (err) throw err;
webpack(webpackConfig, function (err, stats) {
spinner.stop();
if (err) throw err;
process.stdout.write(stats.toString({
colors: true,
modules: false,
children: false,
chunks: false,
chunkModules: false
}) + '\n\n');
if (stats.hasErrors()) {
console.log(chalk.red(' Build failed with errors.\n'));
process.exit(1)
}
console.log(chalk.cyan(' Build complete.\n'));
console.log(chalk.yellow(
' Tip: built files are meant to be served over an HTTP server.\n' +
' Opening index.html over file:// won\'t work.\n'
))
})
});
webpack.prod.conf.js
const paths = require('./paths');
const utils = require('./utils');
const webpack = require('webpack');
const config = require('../config');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin');
const env = process.env.NODE_ENV === 'testing'
? require('../config/test.env')
: require('../config/prod.env');
const webpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true,
usePostCSS: true
})
},
devtool: config.build.productionSourceMap ? config.build.devtool : false,
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].js'),
chunkFilename: utils.assetsPath('js/[id].js')
},
resolve: {
alias: {
settings: `${paths.settings}/dist.js`
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': env
}),
// UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
},
sourceMap: config.build.productionSourceMap,
parallel: true
}),
// extract css into its own file
new ExtractTextPlugin({
filename: utils.assetsPath('css/[name].css'),
// set the following option to `true` if you want to extract CSS from
// codesplit chunks into this main css file as well.
// This will result in *all* of your app's CSS being loaded upfront.
allChunks: false,
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
cssProcessorOptions: config.build.productionSourceMap
? { safe: true, map: { inline: false } }
: { safe: true }
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: config.build.index,
host: '#_host_#',
template: 'index.html',
inject: false,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
chunksSortMode: 'dependency'
}),
// keep module.id stable when vender modules does not change
new webpack.HashedModuleIdsPlugin(),
// enable scope hoisting
new webpack.optimize.ModuleConcatenationPlugin(),
// split vendor js into its own file
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks(module) {
// any required modules inside node_modules are extracted to vendor
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(paths.nodeModules) === 0
);
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
// This instance extracts shared chunks from code splitted chunks and bundles them
// in a separate chunk, similar to the vendor chunk
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: paths.static,
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
]),
// copy any extra assets to root dist
new CopyWebpackPlugin([
{
from: `${paths.root}\\web.config`,
to: config.build.dist,
ignore: ['.*']
}
])
]
});
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin');
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
`\\.(${
config.build.productionGzipExtensions.join('|')
})$`
),
threshold: 10240,
minRatio: 0.8
})
);
}
if (config.build.bundleAnalyzerReport) {
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
webpackConfig.plugins.push(new BundleAnalyzerPlugin());
}
module.exports = webpackConfig;
webpack.base.conf.js
const paths = require('./paths');
const utils = require('./utils');
const config = require('../config');
module.exports = {
context: paths.root,
entry: {
app: './src/main.jsx'
},
output: {
path: config.build.assetsRoot,
filename: '[name].js',
publicPath: process.env.NODE_ENV === 'production'
? config.build.assetsPublicPath
: config.dev.assetsPublicPath
},
resolve: {
extensions: ['.js', '.jsx', '.json'],
alias: {
'#': paths.src,
api: paths.api,
settings: `${paths.settings}/local.js`
}
},
externals: {
bamboraCheckout: 'customcheckout'
},
module: {
rules: [
...(config.dev.useEslint ? [{
test: /\.js$/,
loader: 'eslint-loader',
enforce: 'pre',
include: [paths.src, paths.test],
options: {
formatter: require('eslint-friendly-formatter'),
emitWarning: !config.dev.showEslintErrorsInOverlay
}
}] : []),
{
test: /\.(js|jsx|mjs)$/,
loader: 'babel-loader',
include: [paths.src, paths.test]
},
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('media/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
]
}
};
webpack.cold.conf.js
const paths = require('./paths');
const merge = require('webpack-merge');
const devWebpackConfig = require('./webpack.hot.conf.js');
module.exports = new Promise(resolve => {
devWebpackConfig.then(base => {
let webpackConfig = merge(base, {
resolve: {
alias: {
api: `${paths.api}/fakes`
}
}
});
resolve(webpackConfig);
})
});
If you miss link to your generated style file in index.html then you should search for problem here, because this plugin is responsible for it
new HtmlWebpackPlugin({
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: config.build.index,
host: '#_host_#',
template: 'index.html',
inject: false,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
}
I just looked through plugin documentation, probably you need to remove inject: false. Default is true, and is putting your assets into index.html