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

nextjs12-serverless

v1.0.6

Published

Runs your next.js 12 app with serverless in the cloud

Downloads

309

Readme

:cloud: nextjs12-serverless npm version license

It has never been easier to deploy a next.js application to AWS Lambda!

nextjs12-serverless handles everything for you and deploys your next.js application to AWS Lambda with minimal or even no configuration using the serverless framework.

Table of contents

Installation

npm install --save nextjs12-serverless

During install, a default serverless.yml gets created if you don't already have one (if not, copy it from here). You might want to update it to your needs.

If you are not using a custom server, replace the next binaries in your package.json with nextjs12-serverless:

{
  "scripts": {
-    "dev": "next",
-    "build": "next build",
-    "start": "next start"
+    "dev": "nextjs12-serverless",
+    "build": "nextjs12-serverless build",
+    "start": "nextjs12-serverless start"
  }
}

Or if you are using a custom server, please read using a custom server below.

You are now already good to go and your application is ready for the first deployment (serverless commands) to AWS Lambda. However, if you are using a randomly generated ApiGateway hostname (e.g. nnptap4nw2.execute-api.eu-west-1.amazonaws.com/prod) and you are not using a custom (sub-) domain, please read using ApiGateway hostnames as some small changes are necessary.

Using ApiGateway hostnames

In this section, we cover a few required changes if you want to use the randomly generated ApiGateway hostnames (e.g. nnptap4nw2.execute-api.eu-west-1.amazonaws.com/prod).

If you are always using a dedicated (sub-) domain (e.g. myproduct.com or my.product.com), you don't have to perform these changes. Please note that it is not possible to have a mix: a custom (sub-) domain and a stage prefix (/prod) which you have with ApiGateway hostnames. This is a limitation by next.js as it, unfortunately, doesn't support path prefixes.

Serverless links

If you are using the randomly generated ApiGateway hostnames, you may have noticed that they have the stage as a path prefix (e.g. nnptap4nw2.execute-api.eu-west-1.amazonaws.com/prod).

nextjs12-serverless provides a link component which automatically detects those links and automatically adds the stage prefix if required.

This link component has exactly the same signature as the default next.js link component, so you can simply change the imports:

-import Link from 'next/link';
+import Link from 'nextjs12-serverless/link';

export default () => (
  <Link href="/about">
    <a>I will automatically have the stage prefix if needed</a>
  </Link>
);

Asset prefixes

When you are including assets in your app (e.g. /_next/static/style.css for CSS or an image /_next/static/my-image.png), you would also get a 404 because it doesn't include the stage prefix.

nextjs12-serverless provides a few helper functions which you can use in these cases:

prefixPath(path: string): string

You can pass in any path you want which then gets prefixes if needed. It automatically takes care of full URLs (https://example.com/styles.css) and doesn't prefix these.

getPathPrefix(): string

It returns either the path prefix ('/prod') or an empty string ('') if none is needed for the current request.

If you are using this function instead of prefixPath, you have to take care of full URLs by yourself.

Examples
// ./pages/_document.js
import Document, { Head, Main, NextScript } from 'next/document';
import { prefixPath, getPathPrefix } from 'nextjs12-serverless';

export default class MyDocument extends Document {
  render() {
    return (
      <html>
        <Head>

          <link rel="stylesheet" href={prefixPath('/_next/static/style.css')} />
          {/* or */}
          <link rel="stylesheet" href={getPathPrefix() + '/_next/static/style.css'} />

        </Head>
        <body>

          <img src={prefixPath(require('./my-image.png'))} />
          {/* or */}
          <img src={getPathPrefix() + require('./my-image.png')} />

          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}

If you end up using these helper functions a lot, you may want to create a wrapper component. For example, create a new Image component which automatically prefixes the src attribute.

Using a custom server

There are a few changes needed to perform if you are using a custom server.

First of all, your server file needs to export a handler function which AWS Lambda will then call. nextjs12-serverless/handler provides you a wrapper function for that so you don't have to handle much on your own.

Please note that you should not call app.prepare() by yourself anymore, nextjs12-serverless will automatically do it at the right time. You can just use the callback or handler functions provided.

nextServerless(app: Server, handler: (req, res) => void, runLocal: () => void)

Parameters:

app: Server

This needs to be an instance of the next.js server/app which you create with next({ /* options */ }).

handler: (req, res) => void

The handler function you provide here will be called for every request. You can just pass in the default next.js request handler or use your own function here to fully customize the requests and responses.

You can use the normal req and res objects of an HTTP Node or express server, we automatically map the Lambda event object to them.

runLocal: () => void

When you run the app locally and not in AWS Lambda, you still want to start your own development server. You should do that within this callback function. app.prepare() already got called before this function gets executed so you don't have to do this again.

Examples

const { createServer } = require('http');
const { parse } = require('url');
const next = require('next');
const nextServerless = require('nextjs12-serverless/handler');

const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

const requestHandler = (req, res) => {
  const parsedUrl = parse(req.url, true);
  const { pathname } = parsedUrl;

  // implement a custom behavior for /hello
  if (pathname === '/hello') {
    res.end('hello world');

  // let next.js handle all other requests
  } else {
    handle(req, res, parsedUrl)
  }
};

// export the nextServerless function
module.exports.handler = nextServerless(app, requestHandler, () => {
  // create a normal http node server for local usage
  createServer(requestHandler).listen(3000, (err) => {
    if (err) throw err;
    console.log('> Ready on http://localhost:3000');
  });
});

There are also a few more examples (custom routing, using next-routes or express) in the examples directory.

If you need assistance to get your custom server running, please feel free to create an issue. More examples are also welcome with a PR.

Updating serverless.yml

The last step you have to do when using a custom server is updating your serverless.yml file.

In functions.app.handler, we specify the file and exported function which AWS Lambda should execute for every request. By default, we use the provided server by nextjs12-serverless but since you are using a custom server, you also want to change that.

Simply change this value to the location and exported function of your custom server using the standard Lambda syntax.

For example, if you have a server.js in your root folder, simply use server.handler.

Serverless commands

nextjs12-serverless is fully compatible with the serverless framework so you can use the same commands here.

You can either install serverless locally, globally (npm install --global serverless) or use npx which comes with npm 5.2+ and higher.

A few example commands:

# build the application before deploying it
$ npm run build

# deploy to the default stage
$ npx serverless deploy

# deploy to a specific stage
$ npx serverless deploy --stage prod

# get the server logs
$ npx logs --stage prod -f app

# watch the server logs
$ npx logs --stage prod -f app -t

License

MIT © Cyril Wanner