{"id":15137650,"url":"https://github.com/kyle-mccarthy/nest-next","last_synced_at":"2025-05-15T18:03:54.995Z","repository":{"id":37663093,"uuid":"154581894","full_name":"kyle-mccarthy/nest-next","owner":"kyle-mccarthy","description":"Render Module to add Nextjs support for Nestjs","archived":false,"fork":false,"pushed_at":"2024-06-22T22:08:50.000Z","size":293,"stargazers_count":645,"open_issues_count":23,"forks_count":88,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-05-15T18:03:46.764Z","etag":null,"topics":["nestjs","nextjs"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/kyle-mccarthy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-10-24T23:23:25.000Z","updated_at":"2025-04-25T08:29:12.000Z","dependencies_parsed_at":"2024-06-18T14:03:24.145Z","dependency_job_id":"edf59b27-9482-4f39-8289-bc94f6115598","html_url":"https://github.com/kyle-mccarthy/nest-next","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyle-mccarthy%2Fnest-next","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyle-mccarthy%2Fnest-next/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyle-mccarthy%2Fnest-next/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kyle-mccarthy%2Fnest-next/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kyle-mccarthy","download_url":"https://codeload.github.com/kyle-mccarthy/nest-next/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254394720,"owners_count":22063984,"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":["nestjs","nextjs"],"created_at":"2024-09-26T07:01:25.600Z","updated_at":"2025-05-15T18:03:54.971Z","avatar_url":"https://github.com/kyle-mccarthy.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1 style=\"margin: 0;\"\u003eNest-Next\u003c/h1\u003e\n  \u003cp\u003eRender Module to add Nextjs support for Nestjs.\u003c/p\u003e\n  \u003ca href=\"https://www.npmjs.com/package/nest-next\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/nest-next?style=flat-square\" alt=\"npm\"\u003e\u003c/a\u003e \u003ca href=\"http://makeapullrequest.com\"\u003e\u003cimg src=\"https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square\" alt=\"PRs Welcome\"\u003e\u003c/a\u003e \u003ca href=\"https://github.com/kyle-mccarthy/nest-next/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square\" alt=\"GitHub license\"\u003e\u003c/a\u003e\u003c/p\u003e\n\n\u003c/div\u003e\n\n\u003e nest-next provides a nestjs module to integrate next.js into a nest.js application, it allows the rendering of next.js pages via nestjs controllers and providing initial props to the page as well.\n\n\u003c!-- vim-markdown-toc GFM --\u003e\n\n### Table of Contents\n\n- [Table of Contents](#table-of-contents)\n- [Installation](#installation)\n- [Peer Dependencies](#peer-dependencies)\n- [Usage](#usage)\n- [Configuration](#configuration)\n  - [Views/Pages Folder](#viewspages-folder)\n  - [Dev Mode](#dev-mode)\n  - [tsconfig.json](#tsconfigjson)\n  - [Pass-through 404s](#pass-through-404s)\n- [Rendering Pages](#rendering-pages)\n- [Rendering the initial props](#rendering-the-initial-props)\n- [Handling Errors](#handling-errors)\n  - [Custom error handler](#custom-error-handler)\n    - [ErrorHandler Typedef](#errorhandler-typedef)\n    - [Setting ErrorHandler](#setting-errorhandler)\n    - [Error Flow (Diagram)](#error-flow-diagram)\n- [Examples folder structure](#examples-folder-structure)\n  - [Basic Setup](#basic-setup)\n  - [Monorepo](#monorepo)\n- [Known Issues](#known-issues)\n- [Contributing](#contributing)\n- [License](#license)\n\n\u003c!-- vim-markdown-toc --\u003e\n\n### Installation\n\n```bash\nyarn add nest-next\n\n# or\n\nnpm install nest-next\n```\n\n### Peer Dependencies\n\n- `react`\n- `react-dom`\n- `next`\n\nif you are using next.js with typescript which most likely is the case, you will need to also install the typescript types for react and react-dom.\n\n### Usage\n\nImport the RenderModule into your application's root module and call the forRootAsync method.\n\n```typescript\nimport { Module } from '@nestjs/common';\nimport Next from 'next';\nimport { RenderModule } from 'nest-next';\n\n@Module({\n  imports: [\n    RenderModule.forRootAsync(Next({ dev: process.env.NODE_ENV !== 'production' })),\n    ...\n  ],\n  ...\n})\nexport class AppModule {}\n```\n\n### Configuration\n\nThe RenderModule accepts configuration options as the second argument in the forRootAsync method.\n\n```typescript\ninterface RenderOptions {\n  viewsDir: null | string;\n  dev: boolean;\n}\n```\n\n#### Views/Pages Folder\n\nBy default the the renderer will serve pages from the `/pages/views` dir. Due to limitations with\nNext, the `/pages` directory is not configurable, but the directory within the `/pages` directory is configurable.\n\nThe `viewsDir` option determines the folder inside of `pages` to render from. By default the value is `/views` but this can be changed or set to null to render from the root of `pages`.\n\n#### Dev Mode\n\nBy default the dev mode will be set to `true` unless the option is overwritten. Currently the dev mode determines how the errors should be serialized before being sent to next.\n\n#### tsconfig.json\n\nNext 9 added [built-in zero-config typescript support](https://nextjs.org/blog/next-9#built-in-zero-config-typescript-support). This change is great in general, but next requires specific settings in the tsconfig which are incompatible with what are needed for the server. However, these settings can easily be overridden in the `tsconfig.server.json` file.\n\nIf you are having issues with unexpected tokens, files not emitting when building for production, warnings about `allowJs` and `declaration` not being used together, and other typescript related errors; see the `tsconfig.server.json` [file in the example project](/examples/basic/tsconfig.server.json) for the full config.\n\n#### Pass-through 404s\n\nInstead of having Nest handle the response for requests that 404, they can be forwarded to Next's request handler.\n\n```typescript\nRenderModule.forRootAsync(\n  Next({\n    dev: process.env.NODE_ENV !== 'production',\n    dir: resolve(__dirname, '..'),\n  }),\n  { passthrough404: true, viewsDir: null },\n),\n```\n\nSee [this discussion](https://github.com/kyle-mccarthy/nest-next/issues/38#issuecomment-647867509) for more context.\n\n### Rendering Pages\n\nThe `RenderModule` overrides the Express/Fastify render. To render a page in your controller import\nthe Render decorator from `@nestjs/common` and add it to the method that will render the page. The\npath for the page is relative to the `/pages` directory.\n\n```typescript\nimport { Controller, Get, Render } from '@nestjs/common';\n\n@Controller()\nexport class AppController {\n  @Get()\n  @Render('Index')\n  public index() {\n    // initial props\n    return {\n      title: 'Next with Nest',\n    };\n  }\n}\n```\n\nAdditionally, the render function is made available on the res object.\n\n```typescript\n@Controller()\nexport class AppController {\n  @Get()\n  public index(@Res() res: RenderableResponse) {\n    res.render('Index', {\n      title: 'Next with Nest',\n    });\n  }\n}\n```\n\nThe render function takes in the view, as well as the initial props passed to the page.\n\n```typescript\nrender = (view: string, initialProps?: any) =\u003e any;\n```\n\n### Rendering the initial props\n\nThe initial props sent to the next.js view page can be accessed from the context's query method inside the getInitialProps method.\n\n```typescript\nimport { NextPage, NextPageContext } from 'next';\n\n// The component's props type\ntype PageProps = {\n  title: string;\n};\n\n// extending the default next context type\ntype PageContext = NextPageContext \u0026 {\n  query: PageProps;\n};\n\n// react component\nconst Page: NextPage\u003cPageProps\u003e = ({ title }) =\u003e {\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003e{title}\u003c/h1\u003e\n    \u003c/div\u003e\n  );\n};\n\n// assigning the initial props to the component's props\nPage.getInitialProps = (ctx: PageContext) =\u003e {\n  return {\n    title: ctx.query.title,\n  };\n};\n\nexport default Page;\n```\n\n### Handling Errors\n\nBy default, errors will be handled and rendered with next's error renderer, which uses the [customizable](https://nextjs.org/docs/#custom-error-handling) \\_error page. Additionally, errors can be intercepted by setting your own error handler.\n\n#### Custom error handler\n\nA custom error handler can be set to override or enhance the default behavior. This can be used for things such as logging the error or rendering a different response.\n\nIn your custom error handler you have the option of just intercepting and inspecting the error, or sending your own response. If a response is sent from the error handler, the request is considered done and the error won't be forwarded to next's error renderer. If a response is not sent in the error handler, after the handler returns the error is forwarded to the error renderer. See the request flow below for visual explanation.\n\n##### ErrorHandler Typedef\n\n```typescript\nexport type ErrorHandler = (\n  err: any,\n  req: any,\n  res: any,\n  pathname: any,\n  query: ParsedUrlQuery,\n) =\u003e Promise\u003cany\u003e;\n```\n\n##### Setting ErrorHandler\n\nYou can set the error handler by getting the RenderService from nest's container.\n\n```typescript\n// in main.ts file after registering the RenderModule\n\nconst main() =\u003e {\n  ...\n\n  // get the RenderService\n  const service = server.get(RenderService);\n\n  service.setErrorHandler(async (err, req, res) =\u003e {\n    // send JSON response\n    res.send(err.response);\n  });\n\n  ...\n}\n\n```\n\n##### Error Flow (Diagram)\n\n_The image is linked to a larger version_\n\n[![error filter sequence diagram](./docs/out/error-filter-sequence-sm.png)](./docs/out/error-filter-sequence.png)\n\n### Examples folder structure\n\nFully setup projects can be viewed in the [examples folder](/examples)\n\n#### Basic Setup\n\nNext renders pages from the pages directory. The Nest source code can remain in the default `/src` folder\n\n    /src\n      /main.ts\n      /app.module.ts\n      /app.controller.ts\n    /pages\n      /views\n        /Index.jsx\n    /components\n      ...\n    babel.config.js\n    next.config.js\n    nodemon.json\n    tsconfig.json\n    tsconfig.server.json\n\n#### Monorepo\n\nNext renders pages from the pages directory in the \"ui\" subproject. The Nest project is in the \"server\" folder.\nIn order to make the properties type safe between the \"ui\" and \"server\" projects, there is a folder called \"dto\"\noutside of both projects. Changes in it during \"dev\" runs trigger recompilation of both projects.\n\n    /server\n      /src\n        /main.ts\n        /app.module.ts\n        /app.controller.ts\n      nodemon.json\n      tsconfig.json\n      ...\n    /ui\n      /pages\n        /index.tsx\n        /about.tsx\n      next-env.d.ts\n      tsconfig.json\n      ...\n    /dto\n      /src\n        /AboutPage.ts\n        /IndexPage.ts\n      package.json\n\nTo run this project, the \"ui\" and \"server\" project must be built, in any order. The \"dto\" project will be implicitly built by the \"server\" project. After both of those builds, the \"server\" project can be started in either dev or production mode.\n\nIt is important that \"ui\" references to \"dto\" refer to the TypeScript files (.ts files in the \"src\" folder), and NOT the declaration files (.d.ts files in the \"dist\" folder), due to how Next not being compiled in the same fashion as the server.\n\n### Known issues\n\nCurrently Next [\"catch all routes\"](https://nextjs.org/docs/routing/dynamic-routes#catch-all-routes) pages do not work correctly. See issue [#101](https://github.com/kyle-mccarthy/nest-next/issues/101) for details.\n\n### Contributing\n\nTo contribute make sure your changes pass the test suite. To run test suite `docker`, `docker-compose` are required. Run `npm run test` to run tests. Playwright will be installed with required packages. To run tests in Next development mode run `npm run test-dev`. You can also specify `NODE_VERSION` and major `NEXT_VERSION` variables to run tests in specific environments.\n\n### License\n\nMIT License\n\nCopyright (c) 2018-present Kyle McCarthy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkyle-mccarthy%2Fnest-next","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkyle-mccarthy%2Fnest-next","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkyle-mccarthy%2Fnest-next/lists"}