@@hamedbahram yeah.. I've seen them.. but I haven't seen any project deployment video yet.. please try to make at least one video on it and another request: please make a video on web components with nextjs 13.. I think react 19 will have a built in support for web components.. I guess it's high time for you to create something on that web-component topic..
thank you for your good work, I think there are several ways to create blurred images and serve them. For me I save a blurhash in my database, then during built, I create a base64 image from the from blurhash for images that are inside the initial viewport, for images that are outside the inital viewport i use the blurhash with the react blurhash component. It hink it builts a bit faster like that, because the images do not have to be fetched during built. But I'll try the plaiceholder package, thank you
Great video. Any idea how you would use Plaiceholder if your images are in a client component - I have a lightbox type 3rd party component that uses ref's so needs to be client component but I believe plaiceholder needs to be server based?
So useful but there is two notes: the first one is How can i shows my logo instead of whitespace before rendering the original image. And the second one is , Are there any performance pitfalls for plaiceholer rendering for each request (I mean in server side section) . It seems either each request have a workload to creating blur data or Maybe cache it to save costs?
You can use the `loading` and `onLoadingComplete` events to show your logo and swap it with the actual image when the next/image finishes loading. As far as the performance, if you're pages are static, this process would run at build time and result will be cached as static pages.
Great video sir. 2 questions tho, how do we load two logo images one for dark and light without a mismatch? also how do we set a dynamic hostname in next.config if the image we store has a dynamic url? can we use process.env?
You can use the `next-themes` package and depending on the theme pass the desired url or statically imported image to the next/image component. As far as dynamic hostname, you can use a wildcard pattern to match a range of subdomains and paths. Read here → nextjs.org/docs/app/api-reference/components/image#remotepatterns
Not able to fully watch right now but do you know how much time it takes to generate that base64 image. Is it fine to do this on every request for each image or is it better to generate it on image upload and store that in the database. I'm currently doing the 2nd option because I wasn't sure if it would be a bad idea to generate all of these if you had many on one page. For example with a list of courses with their thumbnail images
How to manage tailwind merge conflict when we use a custom tailwind config. eg, like text-primary - is a color and text-large is a typography sometimes it conflict with wrong one. when i checked the docs it was a bit confusing.
When using custom utilities you should come up with a less conflicting naming convention, or at least follow Tailwind's convention `font-*` for sized and `text-*` for colors.
@@nikhilpsathyanathan We also encountered this issue where Tailwind sometimes confuses custom text classes like text-primary (color) and text-large (typography). Tailwind determines font size-related attributes by checking if the suffix of text- matches a predefined T-shirt size. We solved it using the `extendTailwindMerge` API to define custom merging rules. Here’s how we did it: ``` const twMerge = extendTailwindMerge({ classGroups: { 'font-size': [ { text: [ 'section-title', 'body', 'small', 'extra-small', // ... ], }, ], }, }); export { twMerge }; ``` This approach ensures text-extra-small is treated as a font size, avoiding conflicts. Hope this solves your issue.
@@hamedbahram perhaps I’m thinking about the incorrectly. But a lot of my images are in ‘use client’ components and I’d like to be able to have a placeholder blur on those.
@@zacharystout8573 One solution would ne to try abstracting only the parts that require client-side interactivity into client component and leave the rest on the server.
Does anyone know a good blog or tutorial on revalidating a cached next/image on-demand. I'm using Next 13 and currently when a user uploads a profile picture the first time works but when they update the image with a new one, it registers in Cloudinary but not on the website due to next.js built-in caching functionality. I'm starting to think I may have chosen the wrong tool for the job. I thought I might be able to use revalidateTag if I configured the next config file to enable server actions but that didn't work.
On-demand revalidation should do the job, you can use `revalidatePath` or `revalidateTag` in your server action in response to the user uploading a new image. Watch this video where at the end I show how to use server action via the new `useActioState` hook and `revalidatePath` to purge the cache. ruclips.net/video/EB0Nu_e9wCs/видео.html
That's still loading the original image, the place holder is a very small base64 image that loads very fast instead of a white space while the image is loading.
It seems like you're using the `plaiceholder` on the client side, it need to run server side. You can clone my code and see what you're doing differently.
@@hamedbahram yes,but in my case I want to make a authentication website which authenticate another saas website hosted on the different domain, like Google
Hi Hamed, I tried this but there is error while running the app. As you mention the next.config extension should be .mjs and it is there. Error: layout.js:18 Uncaught (in promise) ReferenceError: require is not defined at Object.sharp (layout.js:18:1) at options.factory (webpack.js?v=1717570510240:715:31)
It seems like you might be using the `plaiceholder` package on the client side. Look where you've defined the `getImage` function and make sure the component using the function is not a using the `use client` directive.
@@hamedbahram yes, you are right 👍. I added getImage function to utils file (which is default in nextjs). Thank you so much for help and nice video. I really helps us.
i am getting an error says "require is not defined" import "sharp"; index.d.ts import type { NextConfig } from "next"; export default function withPlaiceholder(nextConfig: NextConfig): NextConfig; /***/ "sharp": /*!************************!*\ !*** external "sharp" ***! \************************/ /***/ (function(module, __unused_webpack_exports, __webpack_require__) { "use strict"; module.exports = require("sharp"); // this line is highlighted /***/ } ), i installed sharp but still getting the error.
Yes to a full video on the image component and the differences between next image and using an image service such as cloudinary on performance.
I'm thinking the same, and update next/image video.
+1
This would be awesome
nice work bro.. want you to do something with the monorepo with nextjs 13 including the deployment process.. keep this good work up man😀
Thanks! I've a couple of turborepo videos on the channel, seen them?
@@hamedbahram yeah.. I've seen them.. but I haven't seen any project deployment video yet.. please try to make at least one video on it and another request: please make a video on web components with nextjs 13.. I think react 19 will have a built in support for web components.. I guess it's high time for you to create something on that web-component topic..
thank you for your good work, I think there are several ways to create blurred images and serve them. For me I save a blurhash in my database, then during built, I create a base64 image from the from blurhash for images that are inside the initial viewport, for images that are outside the inital viewport i use the blurhash with the react blurhash component. It hink it builts a bit faster like that, because the images do not have to be fetched during built. But I'll try the plaiceholder package, thank you
My pleasure! nice alternative.
Nice work. Can you show how to create Progressive Web Application using nextjs? I think this will be useful to lots of developer.
I agree! Thanks for the suggestion. I'll add that to my schedule.
@@hamedbahram agreed!
Love your nexts videos
Thanks! Welcome to the channel!
Well explained! Thanks.
My pleasure!
Thank you. How can the base64 be the same width and height of the image. The width of the blur is bigger than the image on my project
I actually ChatGPT to help and found a solution 😊
I guess set width and height on the image component should solve it.
Ok great!
Great video. Any idea how you would use Plaiceholder if your images are in a client component - I have a lightbox type 3rd party component that uses ref's so needs to be client component but I believe plaiceholder needs to be server based?
Thank you! You can create your own wrapper server component to create the blurred data and pass it to the 3rd party client component.
Amazing.
Thanks!
So useful but there is two notes: the first one is How can i shows my logo instead of whitespace before rendering the original image. And the second one is , Are there any performance pitfalls for plaiceholer rendering for each request (I mean in server side section) . It seems either each request have a workload to creating blur data or Maybe cache it to save costs?
You can use the `loading` and `onLoadingComplete` events to show your logo and swap it with the actual image when the next/image finishes loading. As far as the performance, if you're pages are static, this process would run at build time and result will be cached as static pages.
Great video sir. 2 questions tho, how do we load two logo images one for dark and light without a mismatch? also how do we set a dynamic hostname in next.config if the image we store has a dynamic url? can we use process.env?
You can use the `next-themes` package and depending on the theme pass the desired url or statically imported image to the next/image component. As far as dynamic hostname, you can use a wildcard pattern to match a range of subdomains and paths. Read here → nextjs.org/docs/app/api-reference/components/image#remotepatterns
@@hamedbahram i am using remote patterns but the hostname is dynamic i can't know it on build time
Not able to fully watch right now but do you know how much time it takes to generate that base64 image. Is it fine to do this on every request for each image or is it better to generate it on image upload and store that in the database. I'm currently doing the 2nd option because I wasn't sure if it would be a bad idea to generate all of these if you had many on one page. For example with a list of courses with their thumbnail images
It loads pretty much at the same rate as if you were importing the image statically.
How to manage tailwind merge conflict when we use a custom tailwind config.
eg, like text-primary - is a color and text-large is a typography sometimes it conflict with wrong one. when i checked the docs it was a bit confusing.
When using custom utilities you should come up with a less conflicting naming convention, or at least follow Tailwind's convention `font-*` for sized and `text-*` for colors.
@@hamedbahram normally we use text-red-200 text-lg it won't conflict. front for font family and weight
@@nikhilpsathyanathan
We also encountered this issue where Tailwind sometimes confuses custom text classes like text-primary (color) and text-large (typography). Tailwind determines font size-related attributes by checking if the suffix of text- matches a predefined T-shirt size. We solved it using the `extendTailwindMerge` API to define custom merging rules.
Here’s how we did it:
```
const twMerge = extendTailwindMerge({
classGroups: {
'font-size': [
{
text: [
'section-title',
'body',
'small',
'extra-small',
// ...
],
},
],
},
});
export { twMerge };
```
This approach ensures text-extra-small is treated as a font size, avoiding conflicts.
Hope this solves your issue.
@@kuan88 thanks man, I was looking for this answer.
How would I extend this to be able to be used in client components?
I'm finding more and more that I need to use the image component inside client components...
The library I'm using in this video runs on the server. What is the reason why you need to run this on the client?
@@hamedbahram perhaps I’m thinking about the incorrectly. But a lot of my images are in ‘use client’ components and I’d like to be able to have a placeholder blur on those.
@@zacharystout8573 One solution would ne to try abstracting only the parts that require client-side interactivity into client component and leave the rest on the server.
for this use methods , only use server components right ?
That's right!
Does anyone know a good blog or tutorial on revalidating a cached next/image on-demand. I'm using Next 13 and currently when a user uploads a profile picture the first time works but when they update the image with a new one, it registers in Cloudinary but not on the website due to next.js built-in caching functionality. I'm starting to think I may have chosen the wrong tool for the job. I thought I might be able to use revalidateTag if I configured the next config file to enable server actions but that didn't work.
On-demand revalidation should do the job, you can use `revalidatePath` or `revalidateTag` in your server action in response to the user uploading a new image. Watch this video where at the end I show how to use server action via the new `useActioState` hook and `revalidatePath` to purge the cache. ruclips.net/video/EB0Nu_e9wCs/видео.html
How to tell the image show up or animate when it's fully loaded? instead of loading from top to bottom.
You can use the loading events on the image component.
My static image does not load with a blur and I did the same changes like you.
It may be happening so fast you can't see it. try throttling your network down to see.
nice but why dont use this style :
setLoading(false)}
/>
?
That's still loading the original image, the place holder is a very small base64 image that loads very fast instead of a white space while the image is loading.
Am I right to assume that your DynamicImage component could not be used in a 'use client' component because of its async nature?
That's right!
i tried this but it keep saying "ReferenceError: require is not defined".
It seems like you're using the `plaiceholder` on the client side, it need to run server side. You can clone my code and see what you're doing differently.
i got rid of this "ReferenceError: require is not defined" error by adding "use server" to the dynamic-image.tsx component
Please 🙏make a video on single sign on
Sure! That'll make a good video, did you mean using Auth.js?
@@hamedbahram yes,but in my case I want to make a authentication website which authenticate another saas website hosted on the different domain, like Google
require is not defined
why ???
You’re using it on the client side!
@@hamedbahram tnx ❤❤
i got rid of this "ReferenceError: require is not defined" error by adding "use server" to the dynamic-image.tsx component
Hi Hamed, I tried this but there is error while running the app. As you mention the next.config extension should be .mjs and it is there.
Error:
layout.js:18 Uncaught (in promise) ReferenceError: require is not defined
at Object.sharp (layout.js:18:1)
at options.factory (webpack.js?v=1717570510240:715:31)
It seems like you might be using the `plaiceholder` package on the client side. Look where you've defined the `getImage` function and make sure the component using the function is not a using the `use client` directive.
@@hamedbahram yes, you are right 👍. I added getImage function to utils file (which is default in nextjs).
Thank you so much for help and nice video. I really helps us.
i am getting an error says "require is not defined"
import "sharp";
index.d.ts
import type { NextConfig } from "next";
export default function withPlaiceholder(nextConfig: NextConfig): NextConfig;
/***/
"sharp": /*!************************!*\
!*** external "sharp" ***!
\************************/
/***/
(function(module, __unused_webpack_exports, __webpack_require__) {
"use strict";
module.exports = require("sharp"); // this line is highlighted
/***/
}
),
i installed sharp but still getting the error.
you're probably using the image in the client-side
You're probably using this on the client-side?
@@hamedbahram i am using the dynamicImage component inside a server component but still getting the error
i got rid of the error by adding "use server" to the dynamic-image.tsx component