useSrcLoader Deep Dive
The useSrcLoader hook is a powerful utility for managing responsive images and CDN-specific URL generation. It centralizes the logic for creating optimized image sources across different screen sizes and providers.
- Image CDN Loaders
- Responsive Images (imgSizes)
- Custom Loaders
- How it Works Step-by-Step
- Full Example
Image CDN Loaders
Archibald supports a wide range of image CDNs out-of-the-box. The hook uses the global configuration to determine which transformation parameters (width, quality, fit, etc.) to append to the URL.
Supported providers include:
- Akamai, AWS CloudFront, Cloudinary, Cloudflare
- Contentful, Fastly, Gumlet, Imgix, Thumbor
- And many others...
Vercel— targets Vercel's built-in image optimization (/_vercel/image), served from the deployment origin. Pair withapp.image.target: 'proxy'when the media host is not publicly reachable (e.g. commerce behind Cloudflare Access) so the optimizer fetches through the media proxy.Mock— a local/dev loader for pre-generated, size-variant static images. It rewrites the_<width>Wtoken in the file name (foo_1400W.webp→foo_828W.webp) so the browser fetches the sized crop directly (no media endpoint/proxy), making responsiveimgSizesvisible without a real CDN. It is a no-op for URLs without such a token (e.g./medias/?context=…). Setapp.image.loader: 'Mock'per environment (e.g.environment/local.ts); do not use it in real environments.
Choosing the image target
app.image.target decides how loaders resolve the base URL, independent of which loader is selected:
direct— build absolute URLs from the configuredprotocol/host/port.proxy— keep URLs relative so requests flow through the media proxy, even when ahostis configured. Use this when the media backend sits behind access control the browser (or the Vercel optimizer) can't satisfy directly.- Unset — legacy implicit behavior: direct when
host+protocolare set, otherwise relative.
Pass absolute: true to useSrcLoader when the consumer can't resolve relative URLs against a current origin — e.g. React Native's expo-image. The (possibly relative) loader result is then prefixed with the configured image origin. Leave it unset on the web, where relative URLs resolve against the page origin.
The provider is typically set in your archibald.config.ts:
// archibald.config.ts
export default {
images: {
loader: 'cloudinary'
}
}
Responsive Images (imgSizes)
The imgSizes parameter allows you to define multiple source sets based on media queries. This is essential for delivering the correctly sized image to different devices (mobile vs. desktop).
const { source, srcMedia } = useSrcLoader({
src: '/hero.jpg',
imgSizes: [
{ maxScreenWidth: 768, width: 400 }, // Mobile
{ minScreenWidth: 769, width: 1200 } // Desktop
]
});
Custom Loaders
If you need to use a provider not supported by default, or if you need custom logic for URL generation, you can provide a loader function.
const customLoader = ({ src, width, quality }) => {
return `https://my-custom-cdn.com/${src}?w=${width}&q=${quality}`;
};
const { source } = useSrcLoader({
src: 'image.jpg',
width: 800,
loader: customLoader
});
How it Works Step-by-Step
- Configuration Loading: The hook retrieves the global image configuration (provider, host, etc.).
- Base Source Generation: It calculates the "default"
sourceURL using the providedsrc,width, andquality. - Media Query Generation: For each entry in
imgSizes:- It generates a standard CSS media query string (e.g.,
(max-width: 768px)). - It generates a specific URL for that size using either the custom
loaderor the default provider logic.
- It generates a standard CSS media query string (e.g.,
- Memoization: Both the primary
sourceand thesrcMediaarray are memoized to prevent unnecessary recalculations during re-renders. - Return: The hook returns the primary
source(for the<img>tag) and thesrcMediaarray (for<source>tags within a<picture>element).
Best Practice: Always wrap your image in a <picture> element when using imgSizes to ensure the browser can pick the most optimal source based on the generated media queries.
Full Example
import { useSrcLoader } from '@archibald/client';
const MyComponent = () => {
// Image data to generate the src url in different sizes with
// current default/custom loader
const imageSizeData = [
{
maxScreenWidth: 1200,
minScreenWidth: 600,
width: 250,
quality: 100
},
{
maxScreenWidth: 599,
width: 150,
quality: 100
},
{
minScreenWidth: 1201,
src: '/image.png'
}
];
// Custom loader to generate src url
const customSrcLoader = ({ src, quality, width, config }) => {
return `<url>/${src}?q=${quality}&w=${width}`;
};
const imageData = {
src: '/image.png',
width: 100,
quality: 100,
imgSizes: imageSizeData,
loader: customSrcLoader
};
const { source, srcMedia } = useSrcLoader(imageData);
return (
<picture>
{srcMedia?.map((media, index) => (
<source key={index} media={media.media} srcSet={media.source} />
))}
<img src={source} alt="Example" />
</picture>
);
};
export default MyComponent;