{"_id":"@anendlesssupply/next-sanity-image","name":"@anendlesssupply/next-sanity-image","dist-tags":{"latest":"6.3.0"},"versions":{"6.3.0":{"name":"@anendlesssupply/next-sanity-image","version":"6.3.0","description":"Utility for using responsive images hosted on the Sanity.io CDN with the Next.js image component.","bugs":{"url":"https://github.com/lorenzodejong/next-sanity-image/issues"},"repository":{"type":"git","url":"git+https://github.com/lorenzodejong/next-sanity-image.git"},"license":"MIT","author":{"name":"Lorenzo de Jong"},"sideEffects":false,"type":"module","exports":{".":{"types":"./dist/index.d.ts","source":"./src/index.ts","require":"./dist/index.cjs","node":{"import":"./dist/index.cjs.js"},"import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"main":"./dist/index.cjs","module":"./dist/index.js","source":"./src/index.ts","types":"./dist/index.d.ts","scripts":{"prebuild":"rimraf dist","build":"pkg build --strict && pkg --strict","lint":"eslint --cache --max-warnings 0 .","prepublishOnly":"pnpm run build","release":"semantic-release","test":"jest"},"browserslist":["> 0.2% and supports es6-module and supports es6-module-dynamic-import and not dead and not IE 11","maintained node versions"],"dependencies":{"@sanity/image-url":"^1.1.0"},"devDependencies":{"@eslint/js":"^9.27.0","@sanity/client":"^5.4.2","@sanity/pkg-utils":"^2.4.10","@sanity/semantic-release-preset":"^4.1.8","@testing-library/react":"^16.3.0","@types/jest":"^28.1.8","@types/node":"^18.19.101","@types/react":"^18.3.21","eslint":"^9.27.0","eslint-config-prettier":"^10.1.5","eslint-plugin-react":"^7.37.5","eslint-plugin-react-hooks":"^5.2.0","globals":"^16.1.0","jest":"^28.1.3","jest-environment-jsdom":"^29.7.0","next":"^15.3.2","prettier":"^3.5.3","prettier-plugin-packagejson":"^2.5.14","react":"^18.3.1","react-dom":"^18.3.1","react-test-renderer":"^18.2.0","rimraf":"^4.4.1","semantic-release":"^24.2.4","ts-jest":"^28.0.8","ts-node":"^10.9.2","typescript":"^4.9.5","typescript-eslint":"^8.32.1"},"peerDependencies":{"@sanity/client":"^5.0.0 || ^6.0.0 || ^7.0.0","next":"^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0","react":"^18.0.0 || ^19.0.0"},"packageManager":"pnpm@8.10.4","gitHead":"88128ea3d234a9f21005773f801f6d41b5e28d12","_id":"@anendlesssupply/next-sanity-image@6.3.0","homepage":"https://github.com/lorenzodejong/next-sanity-image#readme","_nodeVersion":"24.12.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-IC6kUmDaCZiYMZmmGH8TTUg8BZOg4Yt55KmXnNCat29s+oI/aBiIpepacWdhqTFyoM/ALzh6XVx1CM0fdh6ubA==","shasum":"c10c59f671be09490e7cdc87d57dde42f7b9437a","tarball":"https://registry.npmjs.org/@anendlesssupply/next-sanity-image/-/next-sanity-image-6.3.0.tgz","fileCount":9,"unpackedSize":39566,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCbNkl7Wz1u1BM+W3qqQsjlLNZXbEKN9a1nrg7k50W2AQIgKvX/dQNB4IlUBu7lsZOLPV47jMHvcl6XnXCU/8Bkcjo="}]},"_npmUser":{"name":"anendlesssupply","email":"harry@endless.supply"},"directories":{},"maintainers":[{"name":"anendlesssupply","email":"harry@endless.supply"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/next-sanity-image_6.3.0_1769000390262_0.9308951240780112"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-21T12:59:50.162Z","6.3.0":"2026-01-21T12:59:50.399Z","modified":"2026-01-21T12:59:50.576Z"},"maintainers":[{"name":"anendlesssupply","email":"harry@endless.supply"}],"description":"Utility for using responsive images hosted on the Sanity.io CDN with the Next.js image component.","homepage":"https://github.com/lorenzodejong/next-sanity-image#readme","repository":{"type":"git","url":"git+https://github.com/lorenzodejong/next-sanity-image.git"},"author":{"name":"Lorenzo de Jong"},"bugs":{"url":"https://github.com/lorenzodejong/next-sanity-image/issues"},"license":"MIT","readme":"# next-sanity-image\n\nUtility for using images hosted on the [Sanity.io CDN](https://sanity.io) with the [Next.js image component](https://nextjs.org/docs/api-reference/next/image). This library:\n\n-   Supports all [layout options](https://nextjs.org/docs/api-reference/next/image#layout) from the `next/image` component.\n-   Implements the [loader callback](https://nextjs.org/docs/api-reference/next/image#loader) to resolve the corresponding Sanity CDN URL's.\n-   Respects the [image sizes](https://nextjs.org/docs/basic-features/image-optimization#image-sizes) and [device sizes](https://nextjs.org/docs/basic-features/image-optimization#device-sizes) as specified in your Next config.\n-   Respects the [quality](https://nextjs.org/docs/api-reference/next/image#quality) as specified in the `next/image` props.\n-   Allows transforming the image using the [@sanity/image-url builder](https://www.npmjs.com/package/@sanity/image-url).\n-   Automatically sets the width and the height of the Next image component to the corresponding aspect ratio.\n-   Supports Webp formats using automatic content negotation.\n-   Is fully typed and exposes [relevant types](#types).\n\n## Installation\n\n```\nnpm install --save next-sanity-image\n```\n\nThis library also expects you to pass in a [SanityClient instance](https://www.npmjs.com/package/@sanity/client), if you haven't installed this already:\n\n```\nnpm install --save @sanity/client\n```\n\n## Upgrading\n\n### Upgrading from 4.x.x to 5.x.x\n\nVersion 5.0.0 of this library has removed support for the blur options. The reason for this is that this could not be correctly standardised from the library, the only way to support blur up was to request a low quality placeholder image from the Sanity CDN. Sanity already provides a base 64 lqip from the asset's metadata (https://www.sanity.io/docs/image-metadata#74bfd1db9b97).\n\nCheckout the [Responsive layout](#responsive-layout) example on how to use the lqip in your Image component.\n\n## Usage\n\nAll `next/image` component layouts are supported. Below you can find a usage example for each of the supported layouts.\n\n### Responsive layout\n\nIt's recommended to use the responsive layout for the best compatibility with different devices and resolutions. It's required to set the `sizes` attribute using this layout (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-sizes).\n\n```jsx\nimport { createClient } from '@sanity/client';\nimport Img from 'next/image';\nimport { useNextSanityImage } from 'next-sanity-image';\n\n// If you're using a private dataset you probably have to configure a separate write/read client.\n// https://www.sanity.io/help/js-client-usecdn-token\nconst configuredSanityClient = createClient({\n\tprojectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,\n\tdataset: process.env.NEXT_PUBLIC_SANITY_DATASET,\n\tuseCdn: true\n});\n\nconst Page = ({ mySanityData }) => {\n\tconst imageProps = useNextSanityImage(configuredSanityClient, mySanityData.image);\n\n\treturn (\n\t\t<Img\n\t\t\t{...imageProps}\n\t\t\tstyle={{ width: '100%', height: 'auto' }} // layout=\"responsive\" prior to Next 13.0.0\n\t\t\tsizes=\"(max-width: 800px) 100vw, 800px\"\n\t\t\tplaceholder=\"blur\"\n\t\t\tblurDataURL={mySanityData.image.asset.metadata.lqip}\n\t\t/>\n\t);\n};\n\n// Replace this with your logic for fetching data from the Sanity API.\nexport const getServerSideProps = async function (context) {\n\tconst { slug = '' } = context.query;\n\n\tconst data = await configuredSanityClient.fetch(\n\t\t`{\n\t\t\t\"mySanityData\": *[_type == \"mySanityType\" && slug.current == $slug][0] {\n\t\t\t\timage {\n\t\t\t\t\tasset->{\n\t\t\t\t\t\t...,\n\t\t\t\t\t\tmetadata\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}`,\n\t\t{ slug }\n\t);\n\n\treturn { props: data };\n};\n\nexport default Page;\n```\n\n### Intrinsic layout\n\n```jsx\n// ... see \"Responsive layout\"\n\nconst Page = ({ mySanityData }) => {\n\tconst imageProps = useNextSanityImage(configuredSanityClient, mySanityData.image);\n\n\treturn (\n\t\t<Img\n\t\t\t{...imageProps}\n\t\t\tstyle={{ maxWidth: '100%', height: 'auto' }} // layout=\"intrinsic\" prior to Next 13.0.0\n\t\t\tplaceholder=\"blur\"\n\t\t\tblurDataURL={mySanityData.image.asset.metadata.lqip}\n\t\t/>\n\t);\n};\n\n// ... see \"Responsive layout\"\n```\n\n### Fixed layout\n\n```jsx\n// ... see \"Responsive layout\"\n\nconst Page = ({ mySanityData }) => {\n\tconst imageProps = useNextSanityImage(configuredSanityClient, mySanityData.image);\n\n\treturn (\n\t\t<Img\n\t\t\t{...imageProps}\n\t\t\tplaceholder=\"blur\"\n\t\t\tblurDataURL={mySanityData.image.asset.metadata.lqip}\n\t\t/>\n\t);\n};\n\n// ... see \"Responsive layout\"\n```\n\n### Fill layout\n\nOmit the `width` and `height` props returned from `useNextSanityImage` when using a fill layout, as this fills the available space of the parent container. You probably also want to set the `objectFit` prop to specify how the object resizes inside the container.\n\n```jsx\n// ... see \"Responsive layout\"\n\nconst Page = ({ mySanityData }) => {\n\tconst imageProps = useNextSanityImage(configuredSanityClient, mySanityData.image);\n\n\treturn (\n\t\t<Img\n\t\t\tsrc={imageProps.src}\n\t\t\tloader={imageProps.loader}\n\t\t\tfill // layout=\"fill\" prior to Next 13.0.0\n\t\t\tobjectFit=\"contain\"\n\t\t/>\n\t);\n};\n\n// ... see \"Responsive layout\"\n```\n\n## API\n\n### useNextSanityImage\n\nReact hook which handles generating a URL for each of the defined sizes in the [image sizes](https://nextjs.org/docs/basic-features/image-optimization#image-sizes) and [device sizes](https://nextjs.org/docs/basic-features/image-optimization#device-sizes) Next.js options.\n\n#### sanityClient: [`SanityClient`](https://www.npmjs.com/package/@sanity/client)\n\nPass in a configured instance of the SanityClient, used for building the URL using the [@sanity/image-url builder](https://www.npmjs.com/package/@sanity/image-url).\n\n#### image: [`SanityImageSource` | `null`](https://www.npmjs.com/package/@sanity/image-url#imagesource)\n\nA reference to a Sanity image asset, can be retrieved by using the Sanity API. You can pass in any asset that is also supported by the [image() method of @sanity/image-url](https://www.npmjs.com/package/@sanity/image-url#imagesource). This parameter can be set to `null` in order to not load any image.\n\n#### options: UseNextSanityImageOptions\n\n##### imageBuilder?: `function(/* see below */)`\n\n| property                          | type                                                                                    | description                                                                                                    |\n| --------------------------------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |\n| `imageUrlBuilder`                 | [`ImageUrlBuilder`](https://www.npmjs.com/package/@sanity/image-url#usage)              | @sanity/image-url builder to apply image transformations.                                                      |\n| `options`                         | `UseNextSanityImageBuilderOptions`                                                      | Options object with relevant context passed to the callback, see properties below.                             |\n| `options.width`                   | <code>number &#124; null<code>                                                          | The width for the current `srcSet` entry, if set to `null` this is the entry for the `src` fallback attribute. |\n| `options.originalImageDimensions` | `{ width: number, height: number, aspectRatio: number } : UseNextSanityImageDimensions` | Object containing dimensions of the original image passed to the `image` parameter.                            |\n| `options.croppedImageDimensions`  | `{ width: number, height: number, aspectRatio: number } : UseNextSanityImageDimensions` | The cropped dimensions of the image, if a crop is supplied. Otherwise, the same as `originalImageDimensions`.  |\n| `options.quality`                 | <code>number &#124; null<code>                                                          | The quality of the image as passed to the `quality` prop of the `next/image` component.                        |\n\nAn optional function callback which allows you to customize the image using the [`ImageUrlBuilder`](https://www.npmjs.com/package/@sanity/image-url#usage). This function is called for every entry in the [image sizes](https://nextjs.org/docs/basic-features/image-optimization#image-sizes) and [device sizes](https://nextjs.org/docs/basic-features/image-optimization#device-sizes), and is used to define the URL's outputted in the `srcSet` attribute of the image.\n\nDefaults to:\n\n```javascript\n(imageUrlBuilder, options) => {\n\treturn imageUrlBuilder\n\t\t.width(options.width || Math.min(options.originalImageDimensions.width, 1920))\n\t\t.quality(options.quality || 75)\n\t\t.fit('clip');\n};\n```\n\nFor an example on how to use this, read the chapter on [Image transformations](#image-transformations).\n\n#### Return value: UseNextSanityImageProps | null\n\nIf the `image` parameter is set to `null`, the return value of this hook will also be `null`. This allows you to handle any conditional rendering when no image is loaded. If an `image` is set, to following result (`UseNextSanityImageProps`) will be returned:\n\n```javascript\n{\n\tsrc: string,\n\twidth: number,\n\theight: number,\n\t// https://nextjs.org/docs/api-reference/next/image#loader\n\tloader: ImageLoader\n}\n```\n\n## Image transformations\n\nCustom transformations to the resulting image can be made by implementing the `imageBuilder` callback function. Note that it's recommended to implement a memoized callback, either by implementing the function outside of the component function scope or by making use of [`useCallback`](https://reactjs.org/docs/hooks-reference.html#usecallback). Otherwise the props will be recomputed for every render.\n\n```jsx\n//...\n\nconst myCustomImageBuilder = (imageUrlBuilder, options) => {\n\treturn imageUrlBuilder\n\t\t.width(options.width || Math.min(options.originalImageDimensions.width, 800))\n\t\t.blur(20)\n\t\t.flipHorizontal()\n\t\t.saturation(-100)\n\t\t.fit('clip');\n};\n\nconst Page = ({ mySanityData }) => {\n\tconst imageProps = useNextSanityImage(configuredSanityClient, mySanityData.image, {\n\t\timageBuilder: myCustomImageBuilder\n\t});\n\n\treturn <Img {...imageProps} layout=\"responsive\" sizes=\"(max-width: 800px) 100vw, 800px\" />;\n};\n\n//...\n```\n\n### Gotchas\n\n-   Because [next/image](https://nextjs.org/docs/api-reference/next/image) only renders a single `<img />` element with a `srcSet` attribute, the `width` and `height` prop being returned by the React hook is uniform for each size. Cropping an image is possible using the [`ImageUrlBuilder`](https://www.npmjs.com/package/@sanity/image-url#usage), however you have to return an image with the same aspect ratio for each of the defined sizes. Art direction is currently not supported (both by [next/image](https://nextjs.org/docs/api-reference/next/image) and this library).\n\nIf the functionality mentioned above is desired, please file an issue stating your specific use case so we can look at the desired behavior and possibilities.\n\n## Types\n\nThe following types are exposed from the library:\n\n-   [`ImageUrlBuilder`](https://www.npmjs.com/package/@sanity/image-url#usage)\n-   `UseNextSanityImageProps`\n-   `UseNextSanityImageOptions`\n-   `UseNextSanityImageBuilder`\n-   `UseNextSanityImageBuilderOptions`\n-   `UseNextSanityImageDimensions`\n","readmeFilename":"README.md","_rev":"1-ab6948cae4d48cc8feac6f848b9a1d5d"}