npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

serverless-nextjs-lambda-binary-fix

v1.11.4

Published

Serverless nextjs powered by Serverless Components

Downloads

12

Readme

Serverless Nextjs Component

logo

A zero configuration Nextjs 9.0 serverless component with full feature parity.

serverless Build Status Financial Contributors on Open Collective npm version Coverage Status Codacy Badge

Contents

Motivation

Since Nextjs 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. This project is a better version of the serverless plugin which focuses on addressing core issues like next 9 support, better development experience, the 200 CloudFormation resource limit and performance.

Design principles

  1. Zero configuration by default

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

  1. Feature parity with nextjs

Users of this component should be able to use nextjs development tooling, aka next dev. It is the component's job to deploy your application ensuring parity with all of next's features we know and love.

  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

  • [x] Server side rendered pages at the Edge. Pages that need server side compute to render are hosted on Lambda@Edge. The component takes care of all the routing for you so there is no configuration needed. Because rendering happens at the CloudFront edge locations latency is very low!
  • [x] API Routes. Similarly to the server side rendered pages, API requests are also served from the CloudFront edge locations using Lambda@Edge.
  • [x] Dynamic pages / route segments.
  • [x] Automatic prerendering. Statically optimised pages compiled by next are served from CloudFront edge locations with low latency and cost.
  • [x] Client assets. Nextjs build assets /_next/* served from CloudFront.
  • [x] User static / public folders. Any of your assets in the static or public folders are uploaded to S3 and served from CloudFront automatically.

Getting started

Install the next.js component:

npm install serverless-next.js --save-dev

Add your next application to the serverless.yml:

# serverless.yml

myNextApplication:
  component: serverless-next.js

Set your aws credentials in a .env file:

AWS_ACCESS_KEY_ID=accesskey
AWS_SECRET_ACCESS_KEY=sshhh

Set next.js build target to serverless:

// next.config.js

module.exports = {
  target: "serverless"
};

And simply deploy:

$ serverless

Custom Cloudfront configuration

There are four cache behaviours created in Cloudfront (see Architecture section below for more). This option allows one to set cloudfront cache configuration options for the lambda that handles SSR and/or the api lambda. The options that can be set are listed in the aws-cloudfront component.

# serverless.yml

myNextApplication:
  component: serverless-next.js
  inputs:
    cloudfront:
      defaults: # options for lambda that handle SSR
        forward:
          headers: [CloudFront-Is-Desktop-Viewer, CloudFront-Is-Mobile-Viewer, CloudFront-Is-Tablet-Viewer]
      api: # options for lambdas that handle API request
        ttl: 10
      origins: # options for custom origins and behaviors
        - url: /static
          pathPatterns:
            /wp-content/*:
              ttl: 10
        - url: https://old-static.com
          pathPatterns:
            /old-static/*:
              ttl: 10

The example above adds headers that can be forwarded to the SSR lambda, and sets the ttl for api lambdas.

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.

Make sure you've purchased your domain within Route53:

# serverless.yml

myNextApplication:
  component: serverless-next.js
  inputs:
    domain: "example.com" # sub-domain defaults to www

You can also configure a subdomain:

# serverless.yml

myNextApplication:
  component: serverless-next.js
  inputs:
    domain: ["sub", "example.com"] # [ sub-domain, domain ]

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 arn:

# serverless.yml

myNextApplication:
  component: serverless-next.js
  inputs:
    policy: "arn:aws:iam::123456789012:policy/MyCustomPolicy"

Make sure you add CloudWatch log permissions to your custom policy.

Lambda At Edge Configuration

Both default and api edge lambdas will be assigned 512mb of memory by default. This value can be altered by assigning a number to the memory input

# serverless.yml

myNextApplication:
  component: serverless-next.js
  inputs:
    memory: 1024

Values for default and api lambdas can be separately defined by assigning memory to an object like so:

# serverless.yml

myNextApplication:
  component: serverless-next.js
  inputs:
    memory:
      defaultLambda: 1024
      apiLambda: 2048

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

# serverless.yml

myNextApplication:
  component: serverless-next.js
  inputs:
    timeout:
      defaultLambda: 20
      apiLambda: 15

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

You can also set a custom name for default and api lambdas - if not the default is set by the aws-lambda serverless component to the resource id:

# serverless.yml

myNextApplication:
  component: serverless-next.js
  inputs:
    name:
      defaultLambda: fooDefaultLambda
      apiLambda: fooApiLambda

Architecture

architecture

Four Cache Behaviours are created in CloudFront.

The first two _next/* and static/* 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 defines getInitialProps 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/* or static/*. Also, one cache behaviour per route is a bad idea because CloudFront only allows 25 per distribution.

The fourth cache behaviour handles next API requests api/*.

Inputs

| Name | Type | Default Value | Description | | ------------- | ----------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | cloudfront | object | {} | Sets cloudfront cache options for both SSR and api lambdas. Options are defined in the aws-cloudfront component | | | domain | Array | null | For example ['admin', 'portal.com'] | | bucketName | string | null | Custom bucket name where static assets are stored. By default is autogenerated. | | nextConfigDir | string | ./ | Directory where your application next.config.js file is. This input is useful when the serverless.yml is not in the same directory as the next app. Note: nextConfigDir should be set if next.config.js distDir is used | | nextStaticDir | string | ./ | If your static or public directory is not a direct child of nextConfigDir this is needed | | memory | number\|object | 512 | When assigned a number, both the default and api lambdas will assigned memory of that value. When assigned to an object, values for the default and api lambdas can be separately defined | | | timeout | number\|object | 10 | Same as above | | name | string\|object | / | When assigned a string, both the default and api lambdas will assigned name of that value. When assigned to an object, values for the default and api lambdas can be separately defined | | build | boolean\|object | true | When true builds and deploys app, when false assume the app has been built and uses the .next .serverless_nextjs directories in nextConfigDir to deploy. If an object is passed build allows for overriding what script gets called and with what arguments. | | build.cmd | string | node_modules/.bin/next | Build command | | build.args | Array\|string | ['build'] | Arguments to pass to the build | | build.cwd | string | ./ | Override the current working directory | | build.enabled | boolean | true | Same as passing build:false but from within the config | | build.env | object | {} | Add additional environment variables to the script |

Custom inputs can be configured like this:

myNextApp:
  component: serverless-next.js
  inputs:
    bucketName: my-bucket

FAQ

My component doesn't deploy

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

Do

# serverless.yml
myNextApp:
  component: serverless-next.js

myTable:
  component: serverless/aws-dynamodb
  inputs:
    name: Customers
# other components

Don't

# serverless.yml
provider:
  name: aws
  runtime: nodejs10.x
  region: eu-west-1

myNextApp:
  component: serverless-next.js

Resources: ...

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

For deploying, don't run serverless deploy. Simply run serverless and that deploys your components declared in the serverless.yml file.

For more information about serverless components go here.

Should I use the serverless-nextjs-plugin or this component?

Users are encouraged to use this component instead of the serverless-nextjs-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?

See examples/dynamodb-crud for an example Todo application that interacts with DynamoDB.

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

You need to commit your application state in source control. That is the files under the .serverless directory. The serverless team is currently working on remote state storage so this won't be necessary in the future.

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

Serverless next.js is regionless. 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 to us-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 advanced build setup that includes passing additional arguments and environment variables to the build.

# serverless.yml
myDatabase:
  component: MY_DATABASE_COMPNENT
myNextApp:
  component: serverless-next.js
  build:
    args: ["build", "custom/path/to/pages"]
    env:
      DATABASE_URL: ${myDatabase.databaseUrl}

Contributing

Please see the contributing guide.

Contributors

Code Contributors

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

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]