{"id":15296085,"url":"https://github.com/cyrilwanner/next-serverless","last_synced_at":"2025-04-13T19:35:27.468Z","repository":{"id":42006746,"uuid":"140176329","full_name":"cyrilwanner/next-serverless","owner":"cyrilwanner","description":"☁️ next-serverless deploys your next.js application to AWS Lambda with minimal or even no configuration.","archived":false,"fork":false,"pushed_at":"2022-04-19T02:17:19.000Z","size":326,"stargazers_count":82,"open_issues_count":6,"forks_count":7,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-23T20:05:32.098Z","etag":null,"topics":["aws-lambda","nextjs","plugin","react","serverless"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cyrilwanner.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-07-08T14:45:04.000Z","updated_at":"2023-05-27T18:43:51.000Z","dependencies_parsed_at":"2022-08-12T02:10:32.994Z","dependency_job_id":null,"html_url":"https://github.com/cyrilwanner/next-serverless","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrilwanner%2Fnext-serverless","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrilwanner%2Fnext-serverless/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrilwanner%2Fnext-serverless/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cyrilwanner%2Fnext-serverless/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cyrilwanner","download_url":"https://codeload.github.com/cyrilwanner/next-serverless/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248768519,"owners_count":21158654,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-lambda","nextjs","plugin","react","serverless"],"created_at":"2024-09-30T18:09:16.287Z","updated_at":"2025-04-13T19:35:27.445Z","avatar_url":"https://github.com/cyrilwanner.png","language":"JavaScript","funding_links":[],"categories":["Projects"],"sub_categories":[],"readme":"# :cloud: next-serverless [![npm version](https://badgen.net/npm/v/next-serverless)](https://www.npmjs.com/package/next-serverless) [![license](https://badgen.net/npm/license/next-serverless)](https://github.com/cyrilwanner/next-serverless/blob/master/LICENSE)\n\n\u003e It has never been easier to deploy a [next.js](https://github.com/zeit/next.js) application to AWS Lambda!\n\n`next-serverless` handles everything for you and deploys your [next.js](https://github.com/zeit/next.js) application to AWS Lambda with minimal or even no configuration using the [serverless](https://serverless.com/framework/) framework.\n\n## Table of contents\n\n- [Installation](#installation)\n  - [Using ApiGateway hostnames](#using-apigateway-hostnames)\n    - [Serverless links](#serverless-links)\n    - [Asset prefixes](#asset-prefixes)\n  - [Using a custom server](#using-a-custom-server)\n    - [Examples](#examples)\n    - [Updating `serverless.yml`](#updating-serverlessyml)\n- [Serverless commands](#serverless-commands)\n- [License](#license)\n\n## Installation\n\n```\nnpm install --save next-serverless\n```\n\nDuring install, a default `serverless.yml` gets created if you don't already have one (if not, copy it from [here](https://github.com/cyrilwanner/next-serverless/blob/master/default-serverless.yml)).\nYou might want to update it to your needs.\n\nIf you are not using a custom server, replace the `next` binaries in your `package.json` with `next-serverless`:\n\n```diff\n{\n  \"scripts\": {\n-    \"dev\": \"next\",\n-    \"build\": \"next build\",\n-    \"start\": \"next start\"\n+    \"dev\": \"next-serverless\",\n+    \"build\": \"next-serverless build\",\n+    \"start\": \"next-serverless start\"\n  }\n}\n```\n\nOr if you are using a custom server, please read [using a custom server](#using-a-custom-server) below.\n\nYou are now already good to go and your application is ready for the first deployment ([serverless commands](#serverless-commands)) to AWS Lambda.\nHowever, 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](#using-apigateway-hostnames) as some small changes are necessary.\n\n### Using ApiGateway hostnames\n\nIn 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`).\n\nIf you are always using a dedicated (sub-) domain (e.g. `myproduct.com` or `my.product.com`), you don't have to perform these changes.\nPlease 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.\nThis is a limitation by next.js as it, unfortunately, doesn't support path prefixes.\n\n#### Serverless links\n\nIf 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`).\n\n`next-serverless` provides a link component which automatically detects those links and automatically adds the stage prefix if required.\n\nThis link component has exactly the same signature as the default next.js link component, so you can simply change the imports:\n\n```diff\n-import Link from 'next/link';\n+import Link from 'next-serverless/link';\n\nexport default () =\u003e (\n  \u003cLink href=\"/about\"\u003e\n    \u003ca\u003eI will automatically have the stage prefix if needed\u003c/a\u003e\n  \u003c/Link\u003e\n);\n```\n\n#### Asset prefixes\n\nWhen 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.\n\n`next-serverless` provides a few helper functions which you can use in these cases:\n\n##### `prefixPath(path: string): string`\n\nYou 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.\n\n##### `getPathPrefix(): string`\n\nIt returns either the path prefix (`'/prod'`) or an empty string (`''`) if none is needed for the current request.\n\nIf you are using this function instead of `prefixPath`, you have to take care of full URLs by yourself.\n\n##### Examples\n\n```js\n// ./pages/_document.js\nimport Document, { Head, Main, NextScript } from 'next/document';\nimport { prefixPath, getPathPrefix } from 'next-serverless';\n\nexport default class MyDocument extends Document {\n  render() {\n    return (\n      \u003chtml\u003e\n        \u003cHead\u003e\n\n          \u003clink rel=\"stylesheet\" href={prefixPath('/_next/static/style.css')} /\u003e\n          {/* or */}\n          \u003clink rel=\"stylesheet\" href={getPathPrefix() + '/_next/static/style.css'} /\u003e\n\n        \u003c/Head\u003e\n        \u003cbody\u003e\n\n          \u003cimg src={prefixPath(require('./my-image.png'))} /\u003e\n          {/* or */}\n          \u003cimg src={getPathPrefix() + require('./my-image.png')} /\u003e\n\n          \u003cMain /\u003e\n          \u003cNextScript /\u003e\n        \u003c/body\u003e\n      \u003c/html\u003e\n    );\n  }\n}\n```\n\nIf you end up using these helper functions a lot, you may want to create a wrapper component.\nFor example, create a new `Image` component which automatically prefixes the `src` attribute.\n\n### Using a custom server\n\nThere are a few changes needed to perform if you are using a [custom server](https://github.com/zeit/next.js#custom-server-and-routing).\n\nFirst of all, your server file needs to export a handler function which AWS Lambda will then call.\n`next-serverless/handler` provides you a wrapper function for that so you don't have to handle much on your own.\n\nPlease note that you should **not** call `app.prepare()` by yourself anymore, `next-serverless` will automatically do it at the right time.\nYou can just use the callback or handler functions provided.\n\n#### `nextServerless(app: Server, handler: (req, res) =\u003e void, runLocal: () =\u003e void)`\n\nParameters:\n\n##### `app: Server`\n\nThis needs to be an instance of the next.js server/app which you create with `next({ /* options */ })`.\n\n##### `handler: (req, res) =\u003e void`\n\nThe `handler` function you provide here will be called for every request.\nYou can just pass in the default next.js request handler or use your own function here to fully customize the requests and responses.\n\nYou can use the normal `req` and `res` objects of an HTTP Node or express server, we automatically map the Lambda event object to them.\n\n##### `runLocal: () =\u003e void`\n\nWhen you run the app locally and not in AWS Lambda, you still want to start your own development server.\nYou should do that within this callback function.\n`app.prepare()` already got called before this function gets executed so you don't have to do this again.\n\n#### Examples\n\n```js\nconst { createServer } = require('http');\nconst { parse } = require('url');\nconst next = require('next');\nconst nextServerless = require('next-serverless/handler');\n\nconst dev = process.env.NODE_ENV !== 'production';\nconst app = next({ dev });\nconst handle = app.getRequestHandler();\n\nconst requestHandler = (req, res) =\u003e {\n  const parsedUrl = parse(req.url, true);\n  const { pathname } = parsedUrl;\n\n  // implement a custom behavior for /hello\n  if (pathname === '/hello') {\n    res.end('hello world');\n\n  // let next.js handle all other requests\n  } else {\n    handle(req, res, parsedUrl)\n  }\n};\n\n// export the nextServerless function\nmodule.exports.handler = nextServerless(app, requestHandler, () =\u003e {\n  // create a normal http node server for local usage\n  createServer(requestHandler).listen(3000, (err) =\u003e {\n    if (err) throw err;\n    console.log('\u003e Ready on http://localhost:3000');\n  });\n});\n```\n\nThere are also a few more examples (custom routing, using `next-routes` or `express`) in the [examples](https://github.com/cyrilwanner/next-serverless/tree/master/examples/custom-servers) directory.\n\nIf you need assistance to get your custom server running, please feel free to create an issue.\nMore examples are also welcome with a PR.\n\n#### Updating `serverless.yml`\n\nThe last step you have to do when using a custom server is updating your `serverless.yml` file.\n\nIn `functions.app.handler`, we specify the file and exported function which AWS Lambda should execute for every request.\nBy default, we use the provided server by `next-serverless` but since you are using a custom server, you also want to change that.\n\nSimply change this value to the location and exported function of your custom server using the standard Lambda syntax.\n\nFor example, if you have a `server.js` in your root folder, simply use `server.handler`.\n\n## Serverless commands\n\n`next-serverless` is fully compatible with the [serverless](https://serverless.com/framework/) framework so you can use the same commands here.\n\nYou can either install `serverless` locally, globally (`npm install --global serverless`) or use `npx` which comes with npm 5.2+ and higher.\n\nA few example commands:\n\n```bash\n# build the application before deploying it\n$ npm run build\n\n# deploy to the default stage\n$ npx serverless deploy\n\n# deploy to a specific stage\n$ npx serverless deploy --stage prod\n\n# get the server logs\n$ npx logs --stage prod -f app\n\n# watch the server logs\n$ npx logs --stage prod -f app -t\n```\n\n## License\n\n[MIT](https://github.com/cyrilwanner/next-serverless/blob/master/LICENSE) © Cyril Wanner\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcyrilwanner%2Fnext-serverless","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcyrilwanner%2Fnext-serverless","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcyrilwanner%2Fnext-serverless/lists"}