Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Jan 28, 2025. It is now read-only.

⚡ Deploy your Next.js apps on AWS Lambda@Edge via Serverless Components

License

NotificationsYou must be signed in to change notification settings

serverless-nextjs/serverless-next.js

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚠️ Unfortunately, this is no longer maintained for a long time due to lack of time and the complexity of maintaining parity with Next.js. We would like to thank all past users and contributors, and suggest that you use modern alternatives such asOpenNext andSST.

logo

serverlessGitHub contributorsFinancial Contributors on Open Collectivenpm latestnpm alphaBuild StatusEnd-to-end TestsCircleCI Build StatusCodacy BadgecodecovTested Next.js versionsCypress.ioPlatformsTested Node.js versions

A zero configuration Next.js 10/11serverless component for AWS Lambda@Edge aiming for full feature parity.

Please reviewfeatures for a list of currently supported features.

Contents

⚠️ This README reflects the latest changes on themaster branch. It may or may not yet be published to thelatest (stable) oralpha release in npm. Please go toReleases, find the correct@sls-next/serverless-component version you are using, and open the README for that release for more accurate information. If a feature is listed in this README but not working, please first try upgrading to the most recentalpha release in npm.

⚠ this is currently using Serverless Components Beta (not GA version) as the project was started before GA. We are currently reworking how deployments will work in the future and exploring better IaC solutions such as CDK, CDK for Terraform, etc. and will make an announcement before end of the year on any updates.

Motivation

Since Next.js 8.0,serverless mode was introduced which provides a new low level API which projects like this can use to deploy onto different cloud providers. However, Next.js doesn't provide the full serverless routing logic, hence why this project is needed to fill the gap. The long-term vision is to allow you to self-host with various clouds, starting with AWS.

This project is a better version of theserverless plugin which focuses on addressing core issues likenext 9 support,better development experience,the 200 CloudFormation resource limit andperformance.

Design principles

  1. Zero configuration by default

There is little to no configuration needed. You can extend defaults based on your application needs.

  1. Feature parity with Next.js

Users of this component should be able to use Next.js development tooling, akanext dev. It is the component's job to deploy your application ensuring parity with all of next's features we know and love. We try to emulate all or most of the routing and server-side logic from Next.js and optimize it for a serverless environment. Below you can find a list of the features that are currently supported.

  1. Fast deployments / no CloudFormation resource limits.

With a simplified architecture and no use of CloudFormation, there are no limits to how many pages you can have in your application, plus deployment times are very fast! with the exception of CloudFront propagation times of course.

Features

Since we emulate the Next.js routing logic, unfortunately we aren't always at full parity. The following shows all supported features or planned features. If the checkbox is ticked, it means that the feature is supported. Otherwise, it is likely not supported yet or currently in planning or implementation stage. Please refer to an item's description for specific details.

Note that some features may only be on the latestalpha version. If a feature is listed as supported but not working on thelatest tag, it most likely is in thealpha tag. If you can, please help us test the latest alpha changes andsubmit a bug report if you find any issues. Thank you!

Is there a feature that you want but is not yet supported? Please open anew issue to let us know!

Getting started

First, ensure you have Node.js 12+ installed on the deploying machine as all code is now transpiled to ES2019. Add your next application to the serverless.yml:

# serverless.ymlmyNextApplication:component:"@sls-next/serverless-component@{version_here}"# it is recommended you pin the latest stable version of serverless-next.js

🚫If you specify@sls-next/serverless-component in yourserverless.yml file, do not add@sls-next/serverless-component to your package.json file, it is not used and only the version inserverless.yml file is used, which Serverless pulls from npm by itself. If you do not specify the version, it will use thelatest tag, which refers to the latest stable versionhere (i.e not alpha versions).

You can also point it to a local installation, for example if you want to version usingpackage.json.

In this case, configure the following:

# serverless.ymlmyNextApplication:component:"./node_modules/@sls-next/serverless-component"

Then set your AWS credentials as environment variables:

AWS_ACCESS_KEY_ID=accesskeyAWS_SECRET_ACCESS_KEY=sshhh

And simply deploy:

$ serverless

If you have issues deploying due to new serverless version, please try to pin to specific version e.g2.72.2. See#2320 (comment)

[ALPHA - may be buggy] You may also deploy usingnpx @sls-next/serverless-patched (orserverless-patched if you installed it locally), which is a patched version ofserverless that fixes a couple of issues by patching the underlying@serverless/cli: (1) Continuous "Deploying" messages being printed in non-interactive terminals (e.g CI output) that make it hard to debug, and (2) Handles silent Next.js build failures.

It's also recommended to add--debug flag to get more useful logs of what's happening behind the scenes.

🚫Don't attempt to deploy by runningserverless deploy, use onlyserverless

Custom domain name

In most cases you wouldn't want to use CloudFront's distribution domain to access your application. Instead, you can specify a custom domain name.

You can use any domain name but you must be using AWS Route53 for your DNS hosting. To migrate DNS records from an existing domain follow the instructionshere. The requirements to use a custom domain name:

  • Route53 must include ahosted zone for your domain (e.g.mydomain.com) with a set of nameservers.
  • You must update the nameservers listed with your domain name registrar (e.g. namecheap, godaddy, etc.) with those provided for your newhosted zone.

The serverless Next.js component will automatically generate an SSL certificate and create a new record to point to your CloudFront distribution.

# serverless.ymlmyNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:domain:"example.com"# sub-domain defaults to wwwdomainMinimumProtocolVersion:"TLSv1.2_2018"# can be omitted, defaults to "TLSv1.2_2018"

You can also configure asubdomain:

# serverless.ymlmyNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:domain:["sub", "example.com"]# [ sub-domain, domain ]

Custom CloudFront configuration

To specify your own CloudFront inputs, just add anyaws-cloudfront inputs undercloudfront:

# serverless.ymlmyNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:cloudfront:# if you want to use an existing cloudfront distribution, provide it heredistributionId:XYZEXAMPLE#optional# this is the default cache behaviour of the cloudfront distribution# the origin-request edge lambda associated to this cache behaviour does the pages server side renderingdefaults:forward:headers:[CloudFront-Is-Desktop-Viewer,CloudFront-Is-Mobile-Viewer,CloudFront-Is-Tablet-Viewer]# this is the cache behaviour for next.js api pagesapi:minTTL:10maxTTL:10defaultTTL:10# you can set other cache behaviours like "defaults" above that can handle server side rendering# but more specific for a subset of your next.js pages/blog/*:minTTL:1000maxTTL:1000defaultTTL:1000forward:cookies:"all"queryString:false/about:minTTL:3000maxTTL:3000defaultTTL:3000# you can add custom origins to the cloudfront distributionorigins:        -url:/staticpathPatterns:/wp-content/*:minTTL:10maxTTL:10defaultTTL:10        -url:https://old-static.compathPatterns:/old-static/*:minTTL:10maxTTL:10defaultTTL:10        -url:http://old-api.comprotocolPolicy:http-onlypathPatterns:/old-api/*:minTTL:10maxTTL:10defaultTTL:10aliases:["foo.example.com", "bar.example.com"]priceClass:"PriceClass_100"# You can add custom error responseserrorPages:        -code:503path:"/503.html"minTTL:5# optional, minimum ttl the error is cached (default 10)responseCode:500# optional, alters the response codecomment:"a comment"# optional, describes your distributionwebACLId:"arn:aws:wafv2:us-east-1:123456789012:global/webacl/ExampleWebACL/473e64fd-f30b-4765-81a0-62ad96dd167a"# ARN of WAFrestrictions:geoRestriction:restrictionType:"blacklist"# valid values are whitelist/blacklist/none. Set to "none" and omit items to disable restrictionsitems:["AA"]# ISO 3166 alpha-2 country codescertificate:cloudFrontDefaultCertificate:false# specify false and one of IAM/ACM certificates, or specify true and omit IAM/ACM inputs for default certificateacmCertificateArn:"arn:aws:acm:us-east-1:123456789012:certificate/12345678-1234-1234-1234-123456789012"iamCertificateId:"iam-certificate-id"# specify either ACM or IAM certificate, not bothsslSupportMethod:"sni-only"# can be omitted, defaults to "sni-only"minimumProtocolVersion:"TLSv1.2_2019"# can be omitted, defaults to "TLSv1.2_2019"originAccessIdentityId:XYZEXAMPLE#optionalpaths:["/*"]# which paths should be invalidated on deploy, default matches everything, empty array skips invalidation completelywaitBeforeInvalidate:true# by default true, it waits for the CloudFront distribution to have completed before invalidating, to avoid possibly caching old pagetags:# Add any tags you wanttag1:val1tag2:val2

This is particularly useful for caching any of your Next.js pages at CloudFront's edge locations. Seethis for an example application with custom cache configuration.You can alsoupdate an existing cloudfront distribution using custom cloudfront inputs.

Static pages caching

Statically rendered pages (i.e. HTML pages that are uploaded to S3) have the following Cache-Control set:

cache-control: public, max-age=0, s-maxage=2678400, must-revalidate

s-maxage allows Cloudfront to cache the pages at the edge locations for 31 days.max-age=0 in combination withmust-revalidate ensure browsers never cache the static pages. This allows Cloudfront to be in full control of caching TTLs. On every deployment an invalidation/* is created to ensure users get fresh content.

Public directory caching

By default, common image formats(gif|jpe?g|jp2|tiff|png|webp|bmp|svg|ico) under/public or/static foldershave a one-yearCache-Control policy applied(public, max-age=31536000, must-revalidate).You may customize either theCache-Control headervalue and the regex of which files totest, withpublicDirectoryCache:

myNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:publicDirectoryCache:value:public, max-age=604800test:/\.(gif|jpe?g|png|txt|xml)$/i

value must be a validCache-Control policy andtest must be a validregex of the types of files you wish to test.If you don't want browsers to cache assets from the public directory, you can disable this:

myNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:publicDirectoryCache:false

AWS Permissions

By default the Lambda@Edge functions run using AWSLambdaBasicExecutionRole which only allows uploading logs to CloudWatch. If you need permissions beyond this, like for example access to DynamoDB or any other AWS resource you will need your own custom policy or role arn:

Specify policy:

# serverless.ymlmyNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:policy:"arn:aws:iam::123456789012:policy/MyCustomPolicy"

Specify role:

# serverless.ymlmyNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:roleArn:"arn:aws:iam::123456789012:role/MyCustomLambdaRole"

Make sure you add CloudWatch log permissions to your custom policy or role. Minimum policy JSON example:

{"Version":"2012-10-17","Statement": [    {"Effect":"Allow","Resource":"*","Action": ["logs:CreateLogGroup","logs:CreateLogStream","logs:PutLogEvents"      ]    },    {"Effect":"Allow","Resource":"arn:aws:s3:::s3-deployment-bucket-name/*","Action": ["s3:GetObject","s3:PutObject"]    }  ]}

Role should include trust relationship withlambda.amazonaws.com andedgelambda.amazonaws.com.

NOTE: SpecifybucketName and give permissions to access that bucket viapolicy orroleArn so default and API lambdas can access static resources.

AWS Permissions for deployment

The exhaustive list of AWS actions required for a deployment:

  "acm:DescribeCertificate", // only for custom domains  "acm:ListCertificates",    // only for custom domains  "acm:RequestCertificate",  // only for custom domains  "cloudfront:CreateCloudFrontOriginAccessIdentity",  "cloudfront:CreateDistribution",  "cloudfront:CreateInvalidation",  "cloudfront:GetDistribution",  "cloudfront:GetDistributionConfig",  "cloudfront:ListCloudFrontOriginAccessIdentities",  "cloudfront:ListDistributions",  "cloudfront:ListDistributionsByLambdaFunction",  "cloudfront:ListDistributionsByWebACLId",  "cloudfront:ListFieldLevelEncryptionConfigs",  "cloudfront:ListFieldLevelEncryptionProfiles",  "cloudfront:ListInvalidations",  "cloudfront:ListPublicKeys",  "cloudfront:ListStreamingDistributions",  "cloudfront:UpdateDistribution",  "cloudfront:TagResource",         // for adding tags  "cloudfront:UntagResource",       // for adding tags  "cloudfront:ListTagsForResource", // for adding tags  "iam:AttachRolePolicy",  "iam:CreateRole",  "iam:CreateServiceLinkedRole",  "iam:GetRole",  "iam:PutRolePolicy",  "iam:PassRole",  "lambda:CreateFunction",  "lambda:EnableReplication",  "lambda:DeleteFunction",            // only for custom domains  "lambda:GetFunction",  "lambda:GetFunctionConfiguration",  "lambda:PublishVersion",  "lambda:UpdateFunctionCode",  "lambda:UpdateFunctionConfiguration",  "lambda:ListTags",                  // for tagging lambdas  "lambda:TagResource",               // for tagging lambdas  "lambda:UntagResource",             // for tagging lambdas  "route53:ChangeResourceRecordSets", // only for custom domains  "route53:ListHostedZonesByName",  "route53:ListResourceRecordSets",   // only for custom domains  "s3:CreateBucket",  "s3:GetAccelerateConfiguration",  "s3:GetObject",                     // only if persisting state to S3 for CI/CD  "s3:ListBucket",  "s3:PutAccelerateConfiguration",  "s3:PutBucketPolicy",  "s3:PutObject",  "s3:PutBucketTagging",              // for tagging buckets  "s3:GetBucketTagging",              // for tagging buckets  "lambda:ListEventSourceMappings",  "lambda:CreateEventSourceMapping",  "iam:UpdateAssumeRolePolicy",  "iam:DeleteRolePolicy",  "sqs:CreateQueue", // SQS permissions only needed if you use Incremental Static Regeneration. Corresponding SQS.SendMessage permission needed in the Lambda role  "sqs:DeleteQueue",  "sqs:GetQueueAttributes",  "sqs:SetQueueAttributes"

Lambda At Edge Configuration

Thedefault,api, andimage (for Next.js Image Optimization) edge lambdas will be assigned 512mb of memory by default. This value can be altered by assigning a number to thememory input

# serverless.ymlmyNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:memory:1024

Values fordefault,api, andimage lambdas can be separately defined by assigningmemory to an object like so:

# serverless.ymlmyNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:memory:defaultLambda:1024apiLambda:2048imageLambda:2048

The same pattern can be followed for specifying the Node.js runtime (nodejs14.x by default):

# serverless.ymlmyNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:runtime:defaultLambda:"nodejs14.x"apiLambda:"nodejs14.x"imageLambda:"nodejs14.x"# Note that the sharp image library is built for Lambda Node.js 14.x, although it will likely work fine on other runtimes

Similarly, the timeout by default is 10 seconds. To customise you can:

# serverless.ymlmyNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:timeout:defaultLambda:20apiLambda:15imageLambda:15

Note the maximum timeout allowed for Lambda@Edge is 30 seconds. Seehttps://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-requirements-limits.html

You can also set a custom name fordefault,api, andimage lambdas - if not the default is set by theaws-lambda serverless component to the resource id:

# serverless.ymlmyNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:name:defaultLambda:fooDefaultLambdaapiLambda:fooApiLambdaimageLambda:fooImageLambda

There is a fourthregeneration lambda, which can be configured similarly and is used for Incremental Static Regeneration. However, it does not use Lamda@Edge and can, for example, have a longer timeout setting.

Architecture

architecture

Four Cache Behaviours are created in CloudFront.

The first two_next/* andstatic/* forward the requests to S3.

The third is associated to a lambda function which is responsible for handling three types of requests.

  1. Server side rendered page. Any page that definesgetInitialProps method will be rendered at this level and the response is returned immediately to the user.

  2. Statically optimised page. Requests to pages that were pre-compiled by next to HTML are forwarded to S3.

  3. Public resources. Requests to root level resources like/robots.txt,/favicon.ico,/manifest.json, etc. These are forwarded to S3.

The reason why 2. and 3. have to go through Lambda@Edge first is because the routes don't conform to a pattern like_next/* orstatic/*. Also, one cache behaviour per route is a bad idea because CloudFront only allows25 per distribution.

The fourth cache behaviour handles next API requestsapi/*.

Inputs

NameTypeDefault ValueDescription
deploybooleantrueWhen set to false, it will not deploy the app to the provider (e.g AWS).
domainArraynullFor example['admin', 'portal.com']
domainRedirectsobject{}Adds domain-level redirects at the edge using a 308 redirect. Specify an object of domain name -> redirect destination with protocol. For example,www.example.com: https://example.com. Seehere for more information.
bucketNamestringnullCustom bucket name where static assets are stored. By default is autogenerated.
bucketRegionstringnullRegion where you want to host your s3 bucket. Make sure this is geographically closer to the majority of your end users to reduce latency when CloudFront proxies a request to S3.
bucketTagsobjectundefinedCustom bucket tags to set for your bucket. If undefined, the component will not update any tags. If set to an empty object, it will remove all tags.
nextConfigDirstring./Directory where your applicationnext.config.js file is. This input is useful when theserverless.yml is not in the same directory as the next app.
Note:nextConfigDir should be set ifnext.config.jsdistDir is used
nextStaticDirstring./If yourstatic orpublic directory is not a direct child ofnextConfigDir this is needed
descriptionstring*lambda-type*@Edge for Next CloudFront distributionThe description that will be used for both lambdas. Note that "(API)" will be appended to the API lambda description.
policystring|objectarn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRoleThe arn or inline policy that will be assigned to both lambdas.
roleArnstring|objectnullThe arn of role that will be assigned to both lambdas.
runtimestring|objectnodejs14.xWhen assigned a value, both the default and api lambdas will be assigned the runtime defined in the value. When assigned to an object, values for the default and api lambdas can be separately defined
memorynumber|object512When assigned a number, both the default and api lambdas will be assigned memory of that value. When assigned to an object, values for the default and api lambdas can be separately defined
tagsobjectundefinedTags to assign to a Lambda. If undefined, the component will not update any tags. If set to an empty object, it will remove all tags.
timeoutnumber|object10Same as above
handlerstringindex.handlerWhen assigned a value, overrides the default function handler to allow for configuration. Copieshandler.js in route into the Lambda folders. Your handler MUST still call thedefault-handler afterwards or your function won't work with Next.JS
nameobject/Names for all lambdas can be explicitly defined
buildboolean|objecttrueWhen true builds and deploys app, when false assume the app has been built and uses the.next.serverless_nextjs directories innextConfigDir to deploy. If an object is passedbuild allows for overriding what script gets called and with what arguments.
build.cmdstringnode_modules/.bin/nextBuild command, you may pass a no-op command (e.gtrue or: in Unix-based systems) which will then skip the Next.js build
build.argsArray|string['build']Arguments to pass to the build
build.cwdstring./Override the current working directory
build.enabledbooleantrueSame as passingbuild:false but from within the config
build.envobject{}Add additional environment variables to the script
build.postBuildCommandsArray[]Any commands to run post-build and pre-deploy. For example, you can run any custom code on the.serverless_nextjs directory e.g you can copy additional files into the Lambda: see#767 (comment) for an example fornext-18n. Only applies during execution of theserverless command.
build.cleanupDotNextbooleantrueWhether to clean up.next directory before running the build step
build.assetIgnorePatternsstring[][]Glob patterns to ignore when discovering files to copy from _next/static, public, static directories.
build.useV2HandlerbooleanfalseExperimental Set this to true to use V2 handlers which starts to use genericized handlers. Note: this has the functionality ofseparateApiLambda anddisableOriginResponseHandler so it should not be used together. Also, it is not completely optimized yet in terms of code size, but should still be performant. In the future, we will likely use this mode by default.
cloudfrontobject{}Inputs to be passed toaws-cloudfront
certificateArnstring``Specific certificate ARN to use for CloudFront distribution. Helpful if you have a wildcard SSL cert you wish to use. This currently works only in tandem with thedomaininput. Please checkcustom CloudFront configuration for how to specifycertificatewithout needing to use thedomaininput (note that doing so will override any certificate due to the domain input).
domainTypestring"both"Can be one of:"apex"- apex domain only, don't create a www subdomain."www" - www domain only, don't create an apex subdomain."both"- create both www and apex domains when either one is provided.
domainMinimumProtocolVersionstring"TLSv1.2_2018"Can be one of:"SSLv3", "TLSv1", "TLSv1.1_2016", "TLSv1.2_2018", "TLSv1.2_2019", "TLSv1.2_2021" or "TLSv1_2016". Seereference.
publicDirectoryCacheboolean|objecttrueCustomize thepublic/staticfolder asset caching policy. Assigning an object withvalueand/ortestlets you customize the caching policy and the types of files being cached. Assigning false disables caching
useServerlessTraceTargetbooleanfalseUse the experimental-serverless-trace target to build your next app. This is the same build target that Vercel Now uses. See thisRFC for details. Note: while using this, you may need to setNODE_ENVvariable toproduction.
minifyHandlersbooleanfalseUse pre-built minified handlers to reduce code size. Does not minify custom handlers.
enableHTTPCompressionbooleanfalseWhen set totruethe Lambda@Edge functions for SSR and API requests will use Gzip to compress the response. Note that you shouldn't need to enable this because CloudFront will compress responses for you out of the box.
authenticationobjectundefinedAuthentication object for use with basic authentication (available from 1.19.0-alpha.3). It only supports a single username/password combination for now and is inlined in plaintext in the Lambda handler. You must also forward theAuthorizationheader for CloudFront behaviors, e.gdefaults,api/*, and\_next/data/\_.Note: this is meant as a simple means of protecting an environment such as a development/test site, it is not recommended for production use.
authentication.usernamestringundefinedUsername for basic authentication.
enableS3AccelerationbooleantrueWhether to enable S3 transfer acceleration. This may be useful to disable as some AWS regions do not support it. Seereference.
removeOldLambdaVersionsbooleanfalseBasic support for removing old Lambda versions after deploying to ensure. If set to true, every time you deploy it will automatically removes up to ~50 old versions (starting from oldest) of all Lambdas that are not deployed/replicated. If you require more complex strategies, it is recommended to write your own script to remove old versions.

Custom inputs can be configured like this:

myNextApp:component:"@sls-next/serverless-component@{version_here}"inputs:bucketName:my-bucket

CDK Construct

(experimental) - more work required to bring this construct up to speed andalso to reuse some of the serverless logic. As a result the construct islikely to adapt/change accordingly.

Documentation can be found here.

FAQ

How production ready is this?

As we are emulating Next.js routing logic nearly from scratch to optimize it for a serverless environment, there may be some incomplete or missing features (as mentioned earlier). However, we feel that we've covered the majority of features and have added good unit and end-to-end test coverage to ensure stability (e.g across 10+ end-to-end test suites). Several people are using this to power their startup, personal websites, etc.

Cloud provider limitations also apply - for example on AWS Lambda@Edge, there are cold starts, code size limits, 1 MB response size limit, etc to name a few. You are of course also tied to a single platform for now (AWS Lambda@Edge; more coming soon!).

We are also continuing to improve the deployment process by considering better infrastructure-as-code solutions in the near future (CDK, CDK Terraform, Pulumi, etc.).

My component doesn't deploy

Make sure yourserverless.yml uses theserverless-components (beta) format.serverless components differ from the original serverless framework, even though they are both accessible via the same CLI.

Do

# serverless.ymlmyNextApp:component:"@sls-next/serverless-component@{version_here}"myTable:component:serverless/aws-dynamodbinputs:name:Customers# other components

🚫Don't

# serverless.ymlprovider:name:awsruntime:nodejs10.xregion:eu-west-1myNextApp:component:"@sls-next/serverless-component@{version_here}"Resources:...

Note how the correct yaml doesn't declare aprovider,Resources, etc.

For deploying, don't runserverless deploy. Simply runserverless and that deploys your components declared in theserverless.yml file.

For more information about serverless components gohere.

The Lambda@Edge code size is too large

The API handler and default handler packages are deployed separately, but each has a limit of 50 MB zipped or 250 MB uncompressed per AWS - seehere andhere. By design, there is currently only one Lambda@Edge for all page routes and one Lambda@Edge for all API routes. This could lead to code size issues especially if you have many API routes, SSR pages, etc.

If you are encountering code size issues, please try the following:

  • Optimize your code size: reduce # dependencies in your SSR pages and API routes, have fewer SSR pages (i.e don't usegetInitialProps() orgetServerSideProps()).

  • Minify the handler code itself by using theminifyHandlers input. This will reduce handler size from ~500 kB to ~200 kB.

  • Minify/minimize your server-side code using Terser by adding the following Webpack configuration to yournext.config.js. It usesNEXT_MINIMIZE environment variable to tell it to minimize the SSR code. Note that this will increase build times, and minify the code so it could be harder to debug CloudWatch errors.

First, addterser-webpack-plugin to your dependencies. Then updatenext.config.js:

constTerserPlugin=require("terser-webpack-plugin");
webpack:(config,{ buildId, dev, isServer, defaultLoaders, webpack})=>{if(isServer&&!dev&&process.env.NEXT_MINIMIZE==="true"){config.optimization={minimize:true,minimizer:[newTerserPlugin({parallel:true,cache:true,terserOptions:{output:{comments:false},mangle:true,compress:true},extractComments:false})]};}returnconfig;};

Note that if you do not use any API routes, all JS files used only for prerendering static pages are automatically removed from the bundle. However, if you use API routes, we do not remove them as they may be used for preview mode. There's no official/non-hacky way to identify and remove these JS files not used in preview mode even when API routes are used. But we can add a new input to manually exclude them, if needed.

  • Use theuseServerlessTraceTarget option inserverless.yml. This will cause Next.js to not bundle dependencies into each page (instead creating lightweight pages) and thenserverless-next.js will reference a single set of dependencies innode_modules.

Serverless deployment takes a long time and times out with a message like "TimeoutError: Connection timed out after 120000ms"

This is likely either because of a Lambda@Edge code size issue (see above for potential solutions. RelatedGitHub Issue) or if you have a slow network upload speed and/or are trying to deploy a large Lambda package.

In the second case, theaws-sdk npm package used has a default timeout of 120 seconds. Right now this is not configurable, but we may support longer timeouts in the near future (similar toserverless/serverless#937, which only applies to Serverless Framework, not Serverless Components).

When accessing the Host header in my SSR pages or APIs, I get an S3 domain instead of the CloudFront distribution or my domain name

By default, CloudFront sets theHost header to the S3 origin host name. You need to forward theHost header to the origin. See the example below for forwarding it for yourapi/* cache behavior:

myNextApplication:component:"@sls-next/serverless-component@{version_here}"inputs:cloudfront:api/*:forward:headers:[Host]

Should I use theserverless-plugin or this component?

Users are encouraged to use this component instead of theserverless-plugin. This component was built and designed using lessons learned from the serverless plugin.

How do I interact with other AWS Services within my app?

Seeexamples/dynamodb-crud for an example Todo application that interacts with DynamoDB. You can find a full list of exampleshere

[CI/CD] Multi-stage deployments / A new CloudFront distribution is created on every CI build. I wasn't expecting that

Unfortunately, because of the way Serverless Components works (at least the beta version), the deployment state needs to be synced outside of the mainserverless command. So you can try the following solutions:

  1. You need to commit your application state in source control. That is the files under the.serverless directory. Although this is not recommended as it doesn't work well for multiple stages.
  2. Alternatively you could use S3 to store the.serverless files, see an examplehere,here (uses multipleserverless.yml files), orhere (GitHub Actions-based, uses multipleserverless.yml files).
  3. You can also use thedistributionId CloudFront input to specify an existing CloudFront distribution to deploy to.

In the future, we will look to improve this by integrating proper stage management into the component itself.

Why is this still using Serverless Components Beta? Is there a plan to upgrade to GA?

This project was started by the original author when Serverless Components was in beta, and unfortunately GA components was released shortly afterwards. But this grew larger and larger, with several sub-components imported into this monorepo as they weren't maintained by Serverless. And then it became difficult to upgrade.

There was a plan to upgrade to GA components, but it was put on hold for a few reasons:

  • Since there is only one active maintainer, and it's been hard enough keeping up with Next.js parity and fixing bugs
  • Upon analysis of Serverless Components GA, it seems like there may be more drawbacks than benefits: now your code/temporary credentials might have to be built on Serverless infra and thus risks vendor lock-in (whereas beta components doesn't - it primarily provided reusable components but everything happened locally). In addition, it's not as configurable and robust as proper infrastructure-as-code (IaC) solutions, and a lot of components (especially non-AWS resources) are not well maintained. Finally, the current deployment logic is quite fragile and custom-written and requires lots of maintenance to keep up with new cloud provider features.

We are currently looking into proper IaC solutions (such as CDK for Terraform, CDK, Pulumi, etc.) to address this and to ease the burden of maintaining complex deployment logic, so that we can focus on the developer experience and feature parity with Next.js.

Are there plans to expand to other platforms?

Yes! The main blocker was that the Next.js routing logic used to be highly coupled with Lambda@Edge/CloudFront logic. However, we have genericized most of the core logic (into the@sls-next/core package) so that it can be reused in other platforms, simply by creating a wrapping handler, implementing some platform-specific client (e.g to retrieve pages, trigger static regeneration, etc.), and creating a deployer. If you were observant, you'll have noticed a new package currently in the works for Lambda deployments via API Gateway:https://github.com/serverless-nextjs/serverless-next.js/tree/master/packages/libs/lambda. Other platforms like Azure and Google Cloud should hopefully follow soon.

My lambda is deployed tous-east-1. How can I deploy it to another region?

Serverless Next.js isregionless. By design,serverless-next.js applications will be deployed across the globe to every CloudFront edge location. The lambda might look like is only deployed tous-east-1 but behind the scenes, it is replicated to every other region.

I require passing additional information into my build

See the sample below for an advancedbuild setup that includes passing additional arguments and environment variables to the build.

# serverless.ymlmyDatabase:component:MY_DATABASE_COMPONENTmyNextApp:component:"@sls-next/serverless-component@{version_here}"inputs:build:args:["build", "custom/path/to/pages"]env:DATABASE_URL:${myDatabase.databaseUrl}

Concatenating environment variables doesn't seem to work

If you try to concatenate an environment variable with another string, like${env.VARIABLE}-blah, Serverless framework seems to resolve it to only${env.VARIABLE}.

It seems to be a bug in Serverless Components - it may be due to not using the latest GA version, where it might have been fixed (this is still on Components Beta, unfortunately). For now, the workaround is:

  1. Don't concatenate but specify only environment variable, though this means duplicating environment variables.
  2. Follow#530 (comment) and set aserverless.yml variable first, then concatenate:
stage:${env.STAGE}my-app:component:"@sls-next/serverless-component@1.18.0"inputs:domain:      -"${stage}-front-end"      -mydomain.com

I was expecting for automatic subdomain redirection when using the domainType: www/apex input

You can use the newdomainRedirects input, along with forwardingHost header anddomainType: both, to redirect requests to the correct domain. See example configuration below that redirectswww.example.com requests tohttps://example.com.

next-app:component:"../../serverless-components/nextjs-component"inputs:cloudfront:defaults:forward:headers:[Host]domain:["example.com"]domainType:"both"domainRedirects:www.example.com:https://example.com

All of this happens within the Lambda@Edge origin request handlers. Please note that this will not allow you to redirect requests at_next/static/* or/static/*, since those cache behaviors do not have a Lambda@Edge handler attached to them.

Otherwise, you can also use the manual workaround using an S3 bucket outlinedhere.In summary, you will have to create a new S3 bucket and set it up with static website hosting to redirect requests to your supported subdomain type (ex. "www.example.com" or "example.com"). To be able to support HTTPS redirects, you'll need to set up a CloudFront distribution with the S3 redirect bucket as the origin. Finally, you'll need to create an "A" record in Route 53 with your newly created CloudFront distribution as the alias target.

My environment variables set inbuild.env don't show up in my app

To allow your app to access the defined environment variables, you need to expose them via thenext.config.js as outlinedhere.

Given aserverless.yml like this

myApp:inputs:build:env:API_HOST:"http://example.com"

your next.config.js should look like that:

module.exports={env:{API_HOST:process.env.API_HOST}};

502 Error when hitting CloudFront distribution

You may see an error like below:

502 ERRORThe request could not be satisfied.The Lambda function returned invalid JSON: The JSON output is not parsable. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.Generated by cloudfront (CloudFront)

It commonly occurs when the size of the response is too large. Lambda@Edge currently does have a limitation of 1 MB returned by the origin request handler. See:https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-generating-http-responses-in-requests.html#lambda-generating-http-responses-errors. Unfortunately, there may not be a workaround other than trying to ensure your responses are smaller.

Automatic locale detection

Ensure you forwardAccept-Language header via CloudFront configuration, otherewise it is not able to determine which languages the user understands and/or prefers. By default it is forwarded but if you override with your own configuration, you should add it back.

Third party integrations

If you are using third party libraries (onlynext-i18next for now) and use default paths, some files may need to be copied to the Lambda directories. This component will try to detect default files and copy them for you. However, if you have custom config, you may need to write your ownpostBuildCommands to copy files, etc.

Refer to theREADME for more information and caveats.

Reporting Issues

You can open a new issuehere. If posting a problem, please follow thedebugging wiki first for some useful tips, and try to include as much information to reproduce the issue.

If you are reporting a security vulnerability, please follow thesecurity policy instead.

Please note that there is only one core maintainer right now (@dphang), and a handful of community contributors, who all contribute to this library in their free time. So we hope you understand that our response is best-effort and may take several days, or more. So we hope you could at least help debug the issue or provide as much context. In case an issue hasn't been looked at for a long time (> a few weeks) or it seems like a major issue, feel free to mention a maintainer and we will try to prioritize it.

Contributing

We would love if you can help contribute, whether it's coding, triaging or debugging issues, helping with documentation, or financial support! Please see thecontributing guide.

Contributors

Code Contributors

This project exists thanks to all the people who contribute. [Contribute].

Made withcontributors-img.

Financial Contributors

Become a financial contributor and help us sustain our community. [Contribute]

Individuals

Organizations

Support this project with your organization. Your logo will show up here with a link to your website. [Contribute]

About

⚡ Deploy your Next.js apps on AWS Lambda@Edge via Serverless Components

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Sponsor this project

    Contributors117


    [8]ページ先頭

    ©2009-2025 Movatter.jp