How to allow all domains for Image nextjs config? - next.js

I have various image url and changes over time (the image are taken for web by url address and not locally or from a private storage). In order to render <Image /> tag , domains should be passed on to nextjs config.
It isn't possible to pass in 100s of url over time.
How to allow all domains ?
/** #type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
images: {
domains: [
"img.etimg.com",
"assets.vogue.com",
"m.media-amazon.com",
"upload.wikimedia.org",
],
},
};
module.exports = nextConfig;
I tried this but dint work,
"*.com"

It works for me, accordingly next.js documentation:
const nextConfig = {
images: {
remotePatterns: [
{
protocol: "https",
hostname: "**",
},
],
},
};
next.js remote patterns

The Domain is required to be explicit per their documentation
To protect your application from malicious users, you must define a list of image provider domains that you want to be served from the Next.js Image Optimization API.
You can also see that the source code allows for url's to be evaluated, a wildcard is not accepted.
https://github.com/vercel/next.js/blob/canary/packages/next/client/image.tsx#L864
Solve
You should look at a proxy like cloudinary or imgix and allow those domains in the next.config and use their fetch features to load external image.
i.e
With cloudinary as the allowed domain
module.exports = {
images: {
domains: ['res.cloudinary.com'],
},
};
and then in your code
<Image
src="https://res.cloudinary.com/demo/image/fetch/https://a.travel-assets.com/mad-service/header/takeover/expedia_marquee_refresh.jpg"
width={500}
height={500}
/>
Important
The following StackBlitz utilizes their demo account to fetch an external image from Expedia.com, you should get your own account for production.
https://stackblitz.com/edit/nextjs-pxrg99?file=pages%2Findex.js

Related

Firebase dynamic link acting differently if generated on iOS (React Native) vs REST API

We have a functionality to generate dynamic links to our app on iOS using React Native, which works perfectly (identifiable data redacted by replacing them with "our app"):
dynamicLinks().buildShortLink({
link: `https://our_app?referral=${referralCode}`,
domainUriPrefix: 'https://ourapp.page.link',
android: {
packageName: 'app.ourapp.mobile',
},
ios: {
appStoreId: 'XXX',
bundleId: 'app.ourapp.client',
},
navigation: {
forcedRedirectEnabled: true,
},
});
It correctly opens the app if installed, and App Store if not installed.
I need to implement the same functionality on web site, here's my code:
const payload = {
dynamicLinkInfo: {
link: `https://our_app.app?referral=${referralCode}`,
domainUriPrefix: 'https://ourapp.page.link',
androidInfo: {
androidPackageName: 'app.ourapp.mobile',
},
iosInfo: {
iosBundleId: 'XXX',
iosBundleId: 'app.ourapp.client',
},
navigationInfo: {
enableForcedRedirect: true,
},
}
};
// generate page link and redirect there
const result = await fetch('https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=OUR_API_KEY', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(payload)
});
It's the same (with parameter names from React Native changed to REST parameter names respectively, as documented at https://firebase.google.com/docs/reference/dynamic-links/link-shortener)
A link is generated, however when clicked, if the app isn't installed, the page link redirects our website instead of App Store.
When I debug both links using ?d=1 query string parameter, I can indeed notice the difference:
(left: in-app generated, correct. right: REST-generated, incorrect)
Why are these links, generated with the exact same parameters, behaving differently and how can I make the second one work exactly like the first one (redirect to App Store instead of our website)?
After examining closely I've found a typo:
While generating the link in the second example, I was mistakenly using the same key twice:
iosInfo: {
iosBundleId: 'XXX',
iosBundleId: 'app.ourapp.client',
},
Changed the first one to iosAppStoreId and it worked.

How can I make a dynamic route start with an # symbol? Like "mywebsite.com/#username"

My goal is to have two kinds of dynamic routes on the same path. I want:
mywebsite.com/#username to send people to /pages/[username].tsx
mywebsite.com/page-slug to send people to /pages/[pageSlug].tsx
I tried creating two files:
/pages/[pageSlug].tsx
/pages/[...username].tsx
So that [pageSlug].tsx would have priority, and then everything else would go to [...username].tsx, where I would extract the username from the path and render the page.
It works great locally, but on vercel mywebsite.com/#username pages return 404 error.
I have also tried following this advice about doing this with url rewrites, but it doesn't seem to work.
I have created two files:
/pages/[pageSlug].tsx
/pages/user/[username].tsx
Set up the rewrites in next.config.js:
module.exports = {
reactStrictMode: true,
async rewrites() {
return [
{
source: '/:username(#[a-zA-Z0-9]+)/:id*',
destination: "/user/:username/:id*",
}
]
}
}
And set up the links to the user profiles like so:
<Link href="/user/[username]" as={`#${post.author.username}`}>
{post.author.username}
</Link>
Just loading the http://localhost:3080/#lumen works, but when I click on a link I'm getting:
Error: The provided as value (/#lumen) is incompatible with the href value (/user/[username]). Read more: https://nextjs.org/docs/messages/incompatible-href-as
How can I make this work with the rewrites (or in any other way)? Any advice?

NextJS route gives 404 when not using Link

I have a Next.js page, where the pages are statically generated (using next export). It's a dynamic route, but I will only fetch data on the client after the initial page load (in a useEffect).
The path is something like: /pages/foo/[id].tsx. This is in fact the only route which is going to exist.
My problem is:
If I access the URL directly (e.g. typing in https://mysite.fake/foo/1337 into the URL bar) I get a 404.
If I navigate to that route using a <Link /> it does work as expected
If I then reload the page, I get a 404 again.
On local dev, it works fine. The problem only exists when deployed.
The page in question is using the router.query, but I have the same problem with a completely static page (e.g. just /pages/bar/baz.tsx).
Example:
export const Home: NextPage = () => {
const router = useRouter()
const { id } = router.query
const headerText = id ? `Hello ${id.toString()}` : ''
// in a later iteration, I will use the query id to fetch data in a useEffect
return <h1>{headerText}</h1>
}
As far as I understand from the Next.js documentation on dynamic routing and data fetching this should be possible to do.
My next.config.js is very bare:
/** #type {import('next').NextConfig} */
module.exports = {
reactStrictMode: true,
}
What am I doing wrong?

gatsby-plugin-google-analytics + Shopify - Conversions not working

I have a Gatsby site sourcing from Shopify, and I'm having a hard time getting the Acquisition Conversions working.
My guess is that when they go to the Checkout page, since it's on Shopify's domain, it sees that as Direct traffic.
My current configuration is:
{
resolve: `gatsby-plugin-google-analytics`,
options: {
trackingId: "...",
head: true,
anonymize: false,
respectDNT: false,
allowLinker: true,
},
},
I just added that allowLinker in to test today. Is there anything else I'm missing? I'm not too familiar with analytics I'm just a humble javascript farmer.
Thank you
Google Analytics recently changed their API to version 4 and upon other things, they changed the way the tracking identifier is set to the page. I suppose that the plugins will migrate soon to that changes but in the meantime, this is the only plugin available that works with that new API version: gatsby-plugin-google-gtag. So:
// In your gatsby-config.js
module.exports = {
plugins: [
{
resolve: `gatsby-plugin-google-gtag`,
options: {
// You can add multiple tracking ids and a pageview event will be fired for all of them.
trackingIds: [
"GA-TRACKING_ID", // Google Analytics / GA
"AW-CONVERSION_ID", // Google Ads / Adwords / AW
"DC-FLOODIGHT_ID", // Marketing Platform advertising products (Display & Video 360, Search Ads 360, and Campaign Manager)
],
// This object gets passed directly to the gtag config command
// This config will be shared across all trackingIds
gtagConfig: {
optimize_id: "OPT_CONTAINER_ID",
anonymize_ip: true,
cookie_expires: 0,
},
// This object is used for configuration specific to this plugin
pluginConfig: {
// Puts tracking script in the head instead of the body
head: false,
// Setting this parameter is also optional
respectDNT: true,
// Avoids sending pageview hits from custom paths
exclude: ["/preview/**", "/do-not-track/me/too/"],
},
},
},
],
}
All the above parameters are optional, just omit them and replace the GA-TRACKING_ID for your real identifier.
I'm not sure if you ever solved it #cYberSport91, but in the year 2021 AD I am trying to do the same. This is what I found:
Place this snippet in your gatsby-ssr.js or gatsby-browser.js:
exports.onRenderBody = ({ setPostBodyComponents }) => {
const attachCode = `
if (ga) {
ga('require', 'linker');
ga('linker:autoLink', ['destination1.com', 'destination2.com']);
}`
setPostBodyComponents([<script dangerouslySetInnerHTML={{
__html: attachCode
}}/>])
}
Source: Gatsby Git Issues
(Still waiting to confirm with my client whether this solution works)

How to add an optional path parameter when using dynamic routes? [duplicate]

I am trying to create localized routes with optional first param like /lang?/../../, but without a custom server.
From 9.5 NextJS has this option dynamic optionall parameters, if you set the folder or a file with a name:
[[...param]]. I did that.
The problem is that, i have other routes and I want all of them to be with that lang prefix, ut optional with default language, if that lang is not provided
I have a folder [[...lang]] with a file index.js, with simple function component just for testing. Now optional parameter works for the home page / and /en, but I have other files, which I want to be with that optional lang. For the example, I have about.js and I want to access it via /en/about and /about.
I can't put about.js inside [[...lang]], because, I am getting an error:
Failed to reload dynamic routes: Error: Catch-all must be the last part of the URL.
I know what it says and why is that, but I have a fixed collection of languages ['en', 'fr'] and I can check is there a lang.
Is there a way, without a custom server to use optionally a dynamic first part of the path, like
/en/about and /about ?
I think you are talking about this feature. Have a look on this https://nextjs.org/blog/next-9-5#support-for-rewrites-redirects-and-headers
To extend the answer from #Vibhav, in next.config.js:
const nextConfig = {
async rewrites(){
return [
// URLs without a base route lang param like /my-page
{
source: '/',
destination: '/'
},
// URLs with a base route lang param like /en/my-page
{
source: '/:lang*/:page*',
destination: '/:page*'
},
// URLs `/en/post/post_id`
{
source: '/:lang/:path/:page',
destination: '/:path/:page'
},
]
}
};
module.exports = withBundleAnalyzer(nextConfig);
all pages are in the pages folder. Not the best solution for now, because it works in a deep up to like /pages/another-folder/file.
You can even get the lang param in your pages or _app.js:
....
const router = useRouter();
if(router.query.lang){
pageProps.lang = router.query.lang;
}
console.log(pageProps.lang);
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
For URL - /en/my-page, router.query.lang will be equal to en.
For URL - /my-page, router.query.lang will be undefined, but you can set a default lang.

Resources