My blog

Sometimes I win the impostor syndrome

29/04/2024

How to use a different src for the same Image in NextJS?

Let's image that you need imageA for desktop and imageB for mobile screens, using the same component, just changing the image source. Sounds a little common, right? How to achieve that using NextJS? ## How It Works The AdaptiveImage component takes two image sources: one for desktop and another for mobile screens. By leveraging the <source> tag within the <picture> element, it dynamically selects the appropriate image based on the screen size, ensuring optimal loading and rendering performance. ## Key Benefits **Improved Performance** <br/> By preloading the images and specifying different sources based on screen size using media queries, AdaptiveImage minimizes unnecessary loading and rendering, thus enhancing page loading speed and overall performance. **Simplified Implementation** <br/> With a concise and intuitive API, developers can easily integrate AdaptiveImage into their Next.js applications without complex configurations. The component abstracts away the complexities of handling image adaptation, allowing developers to focus on other aspects of their projects. **Enhanced User Experience** <br/> Tailoring image content to different screen sizes enhances the user experience by delivering crisp and appropriately sized images, regardless of the device used. This approach ensures that users receive an optimized viewing experience, leading to increased engagement and satisfaction. ## Leveraging HTML5 Picture Element The `<picture>` element, along with the `<source>` tags, empowers AdaptiveImage to deliver adaptive image rendering effectively. While the `<img>` tag serves as a fallback for unsupported browsers, the `<source>` tags allow specifying multiple image sources based on media queries, enabling seamless adaptation across various devices. ```typescript import { getImageProps, ImageProps, StaticImageData } from 'next/image'; import Head from 'next/head'; const AdaptiveImage = ({ className, alt = 'Hero image', sizes = '100vw', placeholder = 'blur', breakpoint = 640, desktopImage, mobileImage, style = { objectFit: 'cover' }, ...props }: { breakpoint?: number; desktopImage: StaticImageData; mobileImage: StaticImageData; } & Partial<ImageProps>) => { const commonPreload = { rel: 'preload', as: 'image', imageSizes: sizes, }; const common = { alt, sizes, className, style, placeholder, ...props }; const { srcSet: desktop } = getImageProps({ ...common, src: desktopImage }).props; const { srcSet: mobile, ...rest } = getImageProps({ ...common, src: mobileImage }).props; const desktopMedia = `(min-width: ${breakpoint}px)`; const mobileMedia = `(max-width: ${breakpoint - 1}px)`; return ( <> <Head> <link {...commonPreload} media={desktopMedia} href={desktopImage.src} imageSrcSet={desktop} />{' '} <link {...commonPreload} media={mobileMedia} href={mobileImage.src} imageSrcSet={mobile} /> </Head> <picture className={className}> <source media={desktopMedia} srcSet={desktop} /> <source media={mobileMedia} srcSet={mobile} /> <img alt={alt} {...rest} /> </picture> </> ); }; export default AdaptiveImage; ```

#frontend

#nextjs

#responsive

25/07/2024

Can you use a React hook for URL states?

Managing URL parameters in a React application can be simplified with React Router's `useSearchParams` hook. Here's a custom hook, `useQueryParams`, for easy handling of URL query parameters. ## Custom Hook: useQueryParams The `useQueryParams` hook uses `useSearchParams` to get, set, compare, and delete query parameters. ```typescript import { useSearchParams } from 'react-router-dom' const useQueryParams = () => { const [params, setSearchParams] = useSearchParams() const getQueryParam = (key) => params.get(key) const setQueryParam = (key, value) => setSearchParams((prev) => { prev.set(key, value) return prev }) const isQueryParamEqual = (key, value) => params.get(key) === value const getBooleanQueryParam = (key) => params.get(key) === 'true' const setBooleanQueryParam = (key, value) => setSearchParams((prev) => { prev.set(key, value ? 'true' : 'false') return prev }) const deleteQueryParam = (key) => setSearchParams((prev) => { prev.delete(key) return prev }) return { getQueryParam, setQueryParam, isQueryParamEqual, getBooleanQueryParam, setBooleanQueryParam, deleteQueryParam, } } export default useQueryParams ``` ## Advantages of Managing URL States **1) Enhanced User Experience**: Bookmark and share exact app states. <br/> **2) Improved State Management**: Simplifies state management and persists on reload.<br/> **3) SEO Benefits**: Makes dynamic content discoverable by search engines.<br/> **4) Consistent State Across Components**: Easily manage state across components.<br/> **5) Debugging and Testing**: Reproduce and share specific app states for easier debugging.<br/> **6) Flexibility and Scalability**: Efficiently scale state management.<br/> ## Usage Example Here's how you can use the `useQueryParams` hook in a component: ```typescript const MyComponent = () => { const { getQueryParam, setQueryParam, deleteQueryParam } = useQueryParams() useEffect(() => { const value = getQueryParam('myParam') console.log('Current value:', value) }, [getQueryParam]) const handleSetParam = () => { setQueryParam('myParam', 'newValue') } const handleDeleteParam = () => { deleteQueryParam('myParam') } return ( <div> <button onClick={handleSetParam}>Set Param</button> <button onClick={handleDeleteParam}>Delete Param</button> </div> ) } export default MyComponent ``` In this example, `MyComponent` uses the `useQueryParams` hook to get, set, and delete a query parameter called `myParam`. This makes URL state management straightforward and integrates seamlessly with your React application.

#frontend

#react