@nestbolt/medialibrary
Configuration
Complete reference for all MediaModule.forRoot() and forRootAsync() configuration options.
The MediaModule supports both static configuration via forRoot() and dynamic configuration via forRootAsync(). The module is registered globally -- you only need to import it once in your root module, and MediaService becomes available everywhere through dependency injection.
Static Configuration (forRoot)
Use forRoot() when your configuration values are known at compile time:
import { Module } from "@nestjs/common";
import { MediaModule } from "@nestbolt/medialibrary";
@Module({
imports: [
MediaModule.forRoot({
defaultDisk: "local",
disks: {
local: {
driver: "local",
root: "./uploads",
urlBase: "/media",
},
s3: {
driver: "s3",
bucket: "my-app-media",
region: "us-east-1",
prefix: "uploads/",
credentials: {
accessKeyId: "AKIAIOSFODNN7EXAMPLE",
secretAccessKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
},
},
},
maxFileSize: 10 * 1024 * 1024,
prefix: "media",
baseUrl: "https://cdn.example.com",
}),
],
})
export class AppModule {}Async Configuration (forRootAsync)
Use forRootAsync() when configuration depends on other providers, such as a ConfigService:
import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { MediaModule } from "@nestbolt/medialibrary";
@Module({
imports: [
ConfigModule.forRoot(),
MediaModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
defaultDisk: config.get<string>("MEDIA_DISK", "local"),
disks: {
local: {
driver: "local" as const,
root: config.get<string>("UPLOAD_DIR", "./uploads"),
urlBase: config.get<string>("MEDIA_URL_BASE", "/media"),
},
s3: {
driver: "s3" as const,
bucket: config.getOrThrow<string>("S3_BUCKET"),
region: config.get<string>("S3_REGION", "us-east-1"),
prefix: config.get<string>("S3_PREFIX", "media/"),
credentials: {
accessKeyId: config.getOrThrow<string>("AWS_ACCESS_KEY_ID"),
secretAccessKey: config.getOrThrow<string>("AWS_SECRET_ACCESS_KEY"),
},
},
},
maxFileSize: config.get<number>("MAX_FILE_SIZE", 10 * 1024 * 1024),
baseUrl: config.get<string>("CDN_URL"),
}),
}),
],
})
export class AppModule {}forRootAsync Options
| Property | Type | Description |
|---|---|---|
imports | any[] | Modules to import (e.g., [ConfigModule]) |
inject | any[] | Providers to inject into useFactory |
useFactory | (...args) => MediaModuleOptions | Promise<MediaModuleOptions> | Factory function that returns the configuration. Can be async. |
Configuration Options Reference
defaultDisk
defaultDisk: "local";The name of the storage disk to use when no disk is explicitly specified during upload or on a collection. Defaults to "local".
If no disk named "local" is configured in the disks map, a local driver using the current working directory is created automatically.
disks
disks: {
local: { driver: "local", root: "./uploads", urlBase: "/media" },
s3: { driver: "s3", bucket: "my-bucket", region: "us-east-1" },
}A map of named disk configurations. Each key is the disk name, and the value is a LocalDiskConfig or S3DiskConfig object. See Storage Drivers for full details on each driver's options.
You can define as many disks as you need. Different collections or individual uploads can target different disks.
maxFileSize
maxFileSize: 10 * 1024 * 1024; // 10 MBThe global maximum file size in bytes. Any upload exceeding this limit throws a FileIsTooBigException. Defaults to 10485760 (10 MB).
This is a global default. Individual collections can override it with their own maxFileSize() setting, which takes precedence for files uploaded to that collection.
prefix
prefix: "media";An optional path prefix prepended to all stored file paths. For example, with prefix: "media", a file might be stored at media/<uuid>/photo.jpg instead of <uuid>/photo.jpg.
This is useful for organizing files within a shared storage bucket or directory.
baseUrl
baseUrl: "https://cdn.example.com";An optional base URL prepended to all generated media URLs. When set, getUrl() returns URLs like https://cdn.example.com/media/<uuid>/photo.jpg regardless of which disk the file is on.
If not set, URLs are generated by the storage driver itself (e.g., /<urlBase>/<path> for local, or https://<bucket>.s3.<region>.amazonaws.com/<key> for S3).
pathGenerator
import { CustomPathGenerator } from "./custom-path-generator";
MediaModule.forRoot({
pathGenerator: CustomPathGenerator,
});A class implementing the PathGenerator interface. Controls how file paths are generated for originals, conversions, and responsive images. Defaults to DefaultPathGenerator, which uses the media UUID as the directory name:
<uuid>/ -- originals
<uuid>/conversions/ -- conversions
<uuid>/responsive-images/ -- responsive imagesImplement your own for custom directory structures:
import { PathGenerator, MediaEntity } from "@nestbolt/medialibrary";
export class CustomPathGenerator implements PathGenerator {
getPath(media: MediaEntity): string {
return `${media.collectionName}/${media.modelType}/${media.id}/`;
}
getPathForConversions(media: MediaEntity): string {
return `${media.collectionName}/${media.modelType}/${media.id}/conversions/`;
}
getPathForResponsiveImages(media: MediaEntity): string {
return `${media.collectionName}/${media.modelType}/${media.id}/responsive/`;
}
}urlGenerator
import { CustomUrlGenerator } from "./custom-url-generator";
MediaModule.forRoot({
urlGenerator: CustomUrlGenerator,
});A class implementing the UrlGenerator interface. Controls how URLs are generated from media entities. Defaults to DefaultUrlGenerator.
The UrlGenerator interface:
interface UrlGenerator {
getUrl(media: MediaEntity, conversionName?: string): string;
getPath(media: MediaEntity, conversionName?: string): string;
getTemporaryUrl(
media: MediaEntity,
expiration: Date,
conversionName?: string,
options?: Record<string, any>,
): Promise<string>;
}fileNamer
import { CustomFileNamer } from "./custom-file-namer";
MediaModule.forRoot({
fileNamer: CustomFileNamer,
});A class implementing the FileNamer interface. Controls how uploaded files are named on disk. Defaults to DefaultFileNamer.
The FileNamer interface:
interface FileNamer {
generateFileName(originalName: string, media: MediaEntity): string;
}tempDirectory
tempDirectory: "/tmp/media-processing";An optional directory path used for temporary file storage during processing. When not set, the system's default temporary directory is used.
performConversionsSync
performConversionsSync: true;When set, controls whether image conversions are performed synchronously during the upload transaction. Defaults to synchronous execution.
Complete Example
Here is a fully configured module with all options:
import { Module } from "@nestjs/common";
import { ConfigModule, ConfigService } from "@nestjs/config";
import { EventEmitterModule } from "@nestjs/event-emitter";
import { TypeOrmModule } from "@nestjs/typeorm";
import { MediaModule } from "@nestbolt/medialibrary";
import { CustomPathGenerator } from "./media/custom-path-generator";
@Module({
imports: [
ConfigModule.forRoot(),
EventEmitterModule.forRoot(),
TypeOrmModule.forRoot({
type: "postgres",
host: "localhost",
port: 5432,
database: "myapp",
synchronize: false,
}),
MediaModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
defaultDisk: config.get("MEDIA_DISK", "local"),
disks: {
local: {
driver: "local" as const,
root: config.get("UPLOAD_DIR", "./uploads"),
urlBase: "/media",
},
s3: {
driver: "s3" as const,
bucket: config.getOrThrow("S3_BUCKET"),
region: config.get("S3_REGION", "us-east-1"),
prefix: "media/",
},
},
maxFileSize: 25 * 1024 * 1024, // 25 MB
prefix: "app",
baseUrl: config.get("CDN_URL"),
pathGenerator: CustomPathGenerator,
}),
}),
],
})
export class AppModule {}