How to Define a Custom Filename Generator in next-export-optimize-images
Define a filenameGenerator function in your export-images.config.js that receives { path, name, width, extension } and returns a string to control exactly how optimized image files are named during static export.
The next-export-optimize-images library provides a custom filename generator hook that overrides the default image naming convention. This configuration option lives in your project root config file and gives you programmatic control over output paths, enabling cache-busting hashes, custom directory structures, and collision prevention when building static Next.js sites.
Where filenameGenerator is Implemented in the Source Code
The functionality spans three critical areas of the codebase: type definitions, runtime reconstruction, and build-time execution.
Type Definition and Config Loading
In src/utils/getConfig.ts (lines 58–66), the TypeScript interface defines the exact signature your function must match:
filenameGenerator?: (args: {
path: string;
name: string;
width: number;
extension: string;
}) => string;
When your configuration is processed, the library serializes your function to a string and writes it to node_modules/next-export-optimize-images/export-images.config.js. During the build, getConfig.ts (lines 48–55) reconstructs the function using the Function() constructor, allowing you to write executable logic in a JSON-serializable config file.
Execution During the Build Process
The actual invocation happens in src/utils/buildOutputInfo.ts (lines 71–75). If config.filenameGenerator exists, the library calls it with the parsed image metadata; otherwise, it falls back to the default template:
`${pathWithoutName}/${name}_${width}.${extension}`
How filenameGenerator Works Step-by-Step
- Create
export-images.config.jsat your project root and export an object containing yourfilenameGeneratorfunction. withExportImagescopies that configuration object into the package'snode_modulesdirectory, stringifying any functions for transport.getConfigreads the generated file and reconstructs yourfilenameGeneratorusingFunction('return (...)')to restore executable code.- During static export,
buildOutputInforeceives each source image'ssrcand targetwidth, parsing the source intopath,name, andextensioncomponents. - If
filenameGeneratoris defined, the library invokes it with{ path, name, width, extension }and uses the returned string as the final filename underconfig.imageDir. - The resulting file is written to the export folder (e.g.,
out/_next/static/chunks/images/<your-filename>).
Why Use a Custom Filename Generator?
Implementing a custom generator solves specific deployment and caching challenges:
- Namespace control – Organize images into sub-folders or flatten directory structures using custom separators.
- Cache busting – Embed MD5 hashes, timestamps, or content-derived tokens to invalidate CDN caches when images change.
- Collision avoidance – Prevent images with identical filenames from different source directories from overwriting each other (the default pattern only includes the file name and width).
- Legacy compatibility – Match existing folder structures required by downstream CDNs or asset management systems.
filenameGenerator Configuration Examples
Flatten Paths with Hyphens
Replace directory slashes with hyphens to create a flat output structure:
// export-images.config.js
/**
* @type {import('next-export-optimize-images').Config}
*/
module.exports = {
filenameGenerator: ({ path, name, width, extension }) =>
`${path.replace(/^\//, '').replace(/\//g, '-')}-${name}_${width}.${extension}`,
};
Result: /images/sample.png at width 1920 becomes images-sample_1920.png.
Add Content Hash for Cache Busting
Generate unique filenames based on source content to ensure browsers fetch fresh assets:
const crypto = require('crypto');
module.exports = {
filenameGenerator: ({ path, name, width, extension }) => {
const hash = crypto.createHash('md5')
.update(`${path}/${name}.${extension}`)
.digest('hex')
.slice(0, 8);
return `${path.replace(/^\//, '')}/${name}-${hash}-${width}.${extension}`;
},
};
Result: /avatars/user.png becomes avatars/user-1a2b3c4d-300.png.
Preserve Directory Structure with Prefix
Maintain the original hierarchy while placing optimized files under a specific subdirectory:
module.exports = {
filenameGenerator: ({ path, name, width, extension }) => {
const base = path ? `${path}/${name}` : name;
return `optimized/${base}_${width}.${extension}`;
},
};
Result: /blog/2024/hero.png becomes optimized/blog/2024/hero_800.png.
TypeScript Configuration
For type-safe configuration in TypeScript projects:
// export-images.config.ts
import type { Config } from 'next-export-optimize-images';
const config: Config = {
filenameGenerator: ({ path, name, width, extension }) => {
return `${path.replace(/\//g, '_')}_${name}@${width}.${extension}`;
},
};
export = config;
Note: When using TypeScript, compile the file to JavaScript before running Next.js, or rename it to export-images.config.cjs to ensure Node.js can require it.
Summary
- Define
filenameGeneratorinexport-images.config.jsto override default image naming. - The function receives an object containing
path,name,width, andextension, and must return a string. - The library reconstructs your function at runtime using
Function()after serializing it tonode_modules/next-export-optimize-images/export-images.config.js. - During the build,
src/utils/buildOutputInfo.tsinvokes your generator to determine the final output path underconfig.imageDir. - Use custom generators for cache busting, collision prevention, or matching legacy CDN folder structures.
Frequently Asked Questions
What parameters does the filenameGenerator function receive?
The function receives a single object with four properties: path (the directory portion of the source path), name (the filename without extension), width (the target optimization width in pixels), and extension (the file extension). It must return a string representing the desired output filename.
Where does the custom filenameGenerator place output files?
The returned filename is placed under the directory specified by config.imageDir, which defaults to out/_next/static/chunks/images/ within your Next.js export directory. Your returned string can include subdirectories (e.g., subfolder/image.png) to organize the output hierarchy.
Can I use TypeScript for my export-images.config.js file?
Yes, you can write export-images.config.ts and import the Config type from next-export-optimize-images for full type checking. However, you must compile the TypeScript to JavaScript before running the export, or use the .cjs extension and ensure your build pipeline handles the conversion.
What happens if I do not define a filenameGenerator?
If filenameGenerator is undefined, the library uses the default pattern implemented in src/utils/buildOutputInfo.ts: ${pathWithoutName}/${name}_${width}.${extension}. This places images in their original directory structure but appends the width to the filename, which may cause collisions if different source folders contain identical filenames.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →