A drop-in image optimization loader for the Next.js image component next/image
.
Notice: If you look for a complete solution to host a Next.js application with Terraform on AWS, please check out our Terraform Next.js module for AWS.
- ✅ Terraform
v0.13+
- ✅ Serverless image processing powered by AWS Lambda
- ✅ Powerful optimization using the sharp processing library
- ✅ Performant image caching powered by Amazon CloudFront
- ✅ Two-layer caching with CloudFront Origin Shield
- ✅ Support for custom Device Sizes & Image Sizes
The image optimization module is designed as a full stack AWS app. It relies on multiple AWS services and connects them to work as a single application:
Initialize the module by creating a main.tf
file with the following content (you can place the file in the same directory where your Next.js project is located):
# main.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.0"
}
}
}
# Main AWS region where the resources should be created in
# Should be close to where your Next.js deployment is located
provider "aws" {
region = "us-east-1"
}
module "next_image_optimizer" {
source = "milliHQ/next-js-image-optimization/aws"
next_image_domains = ["example.com", "sub.example.com"]
}
output "domain" {
value = module.next_image_optimizer.cloudfront_domain_name
}
Then run Terraform to deploy the image optimiziation module to your AWS account:
terraform init # Only needed on the first time running Terraform
terraform plan # (Optional) See what resources Terraform will create
terraform apply # Deploy the image optimizer module to your AWS account
After Terraform has successfully created all resources in your AWS account, you should see the following output on the terminal:
> Apply complete!
>
> Outputs:
>
> domain = "<distribution-id>.cloudfront.net"
You should save the <distribution-id>.cloudfront.net
output somewhere since you need it in the next step.
In your Next.js project, open or create the next.config.js
file and add the following lines (Remember to replace <distribution-id>
with the output from the previous step):
// next.config.js
module.exports = {
+ images: {
+ path: 'https://<distribution-id>.cloudfront.net/_next/image'
+ },
}
Then rebuild and redeploy your Next.js application to make use of the changed configuration.
- Statically exported Next.js app hosted on S3
Use the image optimizer together with a statically exported Next.js app that is deployed to S3 and CloudFront. - Next.js + Vercel
Use the image optimizer together with a Next.js app deployed on Vercel. - Existing CloudFront
Use the image optimizer with an existing CloudFront distribution.
Name | Version |
---|---|
terraform | >= 0.13 |
aws | >= 4.8 |
Name | Version |
---|---|
aws | >= 4.8 |
Name | Description | Type | Default | Required |
---|---|---|---|---|
cloudfront_acm_certificate_arn | CloudFront ACM certificate to use. | string |
null |
no |
cloudfront_aliases | Custom domain(s) for CloudFront. | list(string) |
[] |
no |
cloudfront_create_distribution | Controls whether a CloudFront distribution should be created. | bool |
true |
no |
cloudfront_enable_origin_shield | Controls whether CloudFront Origin Shield should be enabled on the image optimizer lambdas. | bool |
true |
no |
cloudfront_minimum_protocol_version | The minimum version of the SSL protocol that you want CloudFront to use for HTTPS connections. One of SSLv3, TLSv1, TLSv1_2016, TLSv1.1_2016, TLSv1.2_2018 TLSv1.2_2019 or TLSv1.2_2021. | string |
"TLSv1" |
no |
cloudfront_origin_id | Override the id for the custom CloudFront id. | string |
"tf-next-image-optimizer" |
no |
cloudfront_origin_shield_region | Override the region chosen for the CloudFront origin shield. Use auto to automatically determine the optimal region. |
string |
"auto" |
no |
cloudfront_price_class | Price class for the CloudFront distribution. One of PriceClass_All, PriceClass_200, PriceClass_100. | string |
"PriceClass_100" |
no |
debug_use_local_packages | (Debug) Use local packages instead of downloading them from npm. | bool |
false |
no |
deployment_name | Identifier for the deployment group (only lowercase alphanumeric characters and hyphens are allowed). | string |
"tf-next-image" |
no |
lambda_attach_policy_json | Controls whether lambda_policy_json should be added to IAM role for Lambda function. | bool |
false |
no |
lambda_memory_size | Amount of memory in MB the worker Lambda Function can use. Valid value between 128 MB to 10,240 MB, in 1 MB increments. | number |
1024 |
no |
lambda_policy_json | Additional policy document as JSON to attach to the Lambda Function role. | string |
"" |
no |
lambda_role_permissions_boundary | ARN of IAM policy that scopes aws_iam_role access for the lambda. | string |
null |
no |
lambda_timeout | Max amount of time the worker Lambda Function has to return a response in seconds. Should not be more than 30 (Limited by API Gateway). | number |
30 |
no |
next_image_base_origin | Base URL where requests for absolute image paths should be resolved to. Should not have a trailing slash. | string |
null |
no |
next_image_content_security_policy | Set the value of the Content-Security-Policy header in the response of the image optimizer. | string |
null |
no |
next_image_dangerously_allow_SVG | Enable the optimization of SVG images. | bool |
false |
no |
next_image_device_sizes | Allowed device sizes that should be used for image optimization. | list(number) |
null |
no |
next_image_domains | Allowed origin domains that can be used for fetching images. | list(string) |
[] |
no |
next_image_formats | If the Accept head matches more than one of the configured formats, the first match in the array is used. Therefore, the array order matters. If there is no match, the Image Optimization API will fallback to the original image's format. | list(string) |
[ |
no |
next_image_image_sizes | Allowed image sizes that should be used for image optimization. | list(number) |
null |
no |
next_image_version | Next.js version from where you want to use the image optimizer from. Supports semver ranges. | string |
"12.1.3" |
no |
source_bucket_id | When your static files are deployed to a Bucket (e.g. with Terraform Next.js) the optimizer can pull the source from the bucket rather than over the internet. | string |
null |
no |
tags | Tag metadata to label AWS resources that support tags. | map(string) |
{} |
no |
Name | Description |
---|---|
cloudfront_cache_behavior | Predefined CloudFront cache behavior. Can be used to embed the image optimizer into an existing CloudFront resource. |
cloudfront_cache_policy_id | Cache policy id used for image optimization. |
cloudfront_domain_name | Domain of the internal CloudFront distribution. |
cloudfront_hosted_zone_id | Zone id of the internal CloudFront distribution. |
cloudfront_origin | Predefined CloudFront origin. Can be used to embed the image optimizer into an existing CloudFront resource. |
cloudfront_origin_id | Id of the custom origin used for image optimization. |
cloudfront_origin_request_policy_id | Request policy id used for image optimization. |
- Max file size of a resized image is 6mb (#110)
Resized images returned by the image optimization API cannot exceed 6mb in size, because this is the maximum allowed payload size for AWS Lambda.
The module internally relies on the original Next.js image optimizer. So the versioning of the module is aligned with the version of the corresponding Next.js release.
For example the v10.0.5
version of this Terraform module uses the image optimizer from the Next.js 10.0.5 release.
Please note that we only publish versions >=10.0.5
, for a full list of available versions see the published versions in the Terraform Registry.
Contributions are welcome!
If you want to improve this module, please take a look at our contributing guide.
This project is maintained by milliVolt infrastructure.
We build custom infrastructure solutions for any cloud provider.
Apache-2.0 - see LICENSE for details.
Note: All sample projects in
examples/*
are licensed as MIT to comply with the official Next.js examples.