Security News
PyPI Introduces Digital Attestations to Strengthen Python Package Security
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
serverless-nextjs-plugin
Advanced tools
A serverless framework plugin to deploy nextjs apps.
The plugin targets Next 8 serverless mode
Next 8 released official support for serverless! It doesn't work out of the box with AWS Lambdas, instead, next provides a low level API which this plugin uses to deploy the serverless pages.
Nextjs serverless page handler signature:
exports.render = function(req, res) => {...}
AWS Lambda handler:
exports.handler = function(event, context, callback) {...}
A compat layer between the nextjs page bundles and AWS Lambda is added at build time:
const compat = require("next-aws-lambda");
const page = require(".next/serverless/pages/somePage.js");
module.exports.render = (event, context, callback) => {
const { req, res } = compat(page)(event, callback);
page.render(req, res);
};
npm install --save-dev serverless-nextjs-plugin
Out of the box, the plugin won't require any configuration. If you need to override any defaults check this.
For example:
nextApp
│ next.config.js
│ serverless.yml
└───pages
│ │ home.js
│ │ about.js
│ │ admin.js
Edit the serverless.yml and add:
plugins:
- serverless-nextjs-plugin
package:
exclude:
- ./**
You can exclude everything. The plugin makes sure the page handlers are included in the artifacts.
If you don't want to manage uploading the next static assets yourself, like uploading them to a CDN, the plugin can do this for you by hosting the asset files on S3.
The easiest way is to use a valid bucket URL in the assetPrefix
field of your next configuration:
// next.config.js
module.exports = {
assetPrefix: "https://s3.amazonaws.com/your-bucket-name"
};
The plugin will create a new S3 Bucket using the parsed name. On deployment, static assets will be uploaded to the bucket provisioned.
Alternatively, if you just want the assets to get uploaded to S3, you can provide the bucket name via the plugin config:
# serverless.yml
plugins:
- serverless-nextjs-plugin
custom:
serverless-nextjs:
assetsBucketName: "your-bucket-name"
Static files can be served by following the NextJs convention of using a static
and public
folder.
From your code you can then reference those files with a /static
URL:
function MyImage() {
return <img src="/static/my-image.png" alt="my image" />
}
export default MyImage
To serve static files from the root directory you can add a folder called public and reference those files from the root, e.g: /robots.txt.
Note that for this to work, an S3 bucket needs to be provisioned as per hosting-static-assets.
For production deployments, enabling CloudFront is recommended:
# serverless.yml
plugins:
- serverless-nextjs-plugin
custom:
serverless-nextjs:
assetsBucketName: "your-bucket-name"
cloudFront: true
By doing this, a CloudFront distribution will be created in front of your next application to serve any static assets from S3 and the pages from Api Gateway.
Note that deploying the stack for the first time will take considerably longer, as CloudFront takes time propagating the changes, typically 10 - 20mins.
serverless deploy
When running serverless deploy
all your next pages will be automatically compiled, packaged and deployed.
The Lambda functions created for each page have by default the following configuration:
handler: /path/to/page/handler.render
events:
- http:
path: pageName # home, about, etc. Unless is the index page which is served at /
method: get
- http:
path: pageName # home, about, etc. Unless is the index page which is served at /
method: head
If you need to deploy just one of your pages, simply run:
serverless deploy function --function pageFunctionName
where pageFunctionName
will be the page file name + "Page"
. For example, to deploy pages/home.js
, you can run:
serverless deploy function --function homePage
You may want to have a different configuration for one or more of your page functions. This is possible by setting the pageConfig
key in the plugin config:
plugins:
- serverless-nextjs-plugin
custom:
serverless-nextjs:
pageConfig:
about:
memorySize: 512 # default is 1024
home:
timeout: 10 # default is 6
If you need to change the default configuration, such as memorySize
, timeout
etc. use the top level provider
which will override all the functions configuration. For example, to change the memorySize to 512MB:
provider:
name: aws
runtime: nodejs8.10
memorySize: 512
...
You can also add configuration for all page functions by adding an asterisk entry (*
) to pageConfig
. This is particularly useful when you have other functions in your service (i.e. an api
) aside from the page functions and you only want to apply configuration changes to the latter:
plugins:
- serverless-nextjs-plugin
custom:
serverless-nextjs:
pageConfig:
"*":
layers:
- arn:aws:lambda:${self:provider.region}:553035198032:layer:nodejs12:1
You can set any function property described here.
The default page routes follow the same convention as next useFileSystemPublicRoutes
documented here.
E.g.
page | path |
---|---|
pages/index.js | / |
pages/post.js | /post |
pages/blog/index.js | /blog |
pages/categories/uno/dos.js | /categories/uno/dos |
You may want to serve your page from a different path. This is possible by setting your own http path in the routes
config. For example for pages/post.js
:
class Post extends React.Component {
static async getInitialProps({ query }) {
return {
slug: query.slug
};
}
render() {
return <h1>Post page: {this.props.slug}</h1>;
}
}
export default Post;
plugins:
- serverless-nextjs-plugin
custom:
serverless-nextjs:
routes:
- src: post
path: posts/{slug}
request:
parameters:
paths:
slug: true
404 or 500 errors are handled both client and server side by a default component error.js
, same as documented here.
Simply add pages/_error.js
:
class Error extends React.Component {
static getInitialProps({ res, err }) {
const statusCode = res ? res.statusCode : err ? err.statusCode : null;
return { statusCode };
}
render() {
return (
<p>
{this.props.statusCode
? `An error ${this.props.statusCode} occurred on server (╯°□°)╯︵ ┻━┻`
: "An error occurred on client"}
</p>
);
}
}
export default Error;
If you need to customize the lambda handler you can do so by providing a path to your own handler in the customHandler
field. Note that it resolves the path to the custom handler relative to your next.config.js
.
plugins:
- serverless-nextjs-plugin
custom:
serverless-nextjs:
customHandler: ./handler.js
The custom handler needs to look something like this:
const compat = require("next-aws-lambda");
module.exports = page => {
const handler = (event, context, callback) => {
// do any stuff you like
// this makes sure the next page renders
compat(page)(event, context, callback);
// do any other stuff you like
};
return handler;
};
Plugin config key | Default Value | Description |
---|---|---|
nextConfigDir | ./ | Path to parent directory of next.config.js . |
assetsBucketName | <empty> | Creates an S3 bucket with the name provided. The bucket will be used for uploading next static assets. |
cloudFront | false | Set to true to create a cloud front distribution in front of your nextjs application. |
routes | [] | Array of custom routes for the next pages. |
customHandler | <empty> | Path to your own lambda handler. |
uploadBuildAssets | true | In the unlikely event that you only want to upload static or public dirs, set this to false . |
Beware this plugin relies on CloudFormation which has a hard limit of 200 resources. If you have a large number of pages in your application it is very likely that you will hit this limit. Contributions are welcome to investigate how this could be worked around by using something like https://github.com/dougmoscrop/serverless-plugin-split-stacks.
See the examples/
directory.
Please see the contributing guide.
FAQs
A serverless plugin for nextjs 8 serverless target
The npm package serverless-nextjs-plugin receives a total of 108 weekly downloads. As such, serverless-nextjs-plugin popularity was classified as not popular.
We found that serverless-nextjs-plugin demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.