{"id":19683864,"url":"https://github.com/prisma/fullstack-prisma-nextjs-blog","last_synced_at":"2025-04-05T12:01:45.119Z","repository":{"id":42563533,"uuid":"479452323","full_name":"prisma/fullstack-prisma-nextjs-blog","owner":"prisma","description":"Fullstack Blog with Next.js and Prisma","archived":false,"fork":false,"pushed_at":"2025-03-29T00:14:53.000Z","size":57,"stargazers_count":126,"open_issues_count":14,"forks_count":33,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-02T21:18:23.446Z","etag":null,"topics":["nextjs","postgres","prisma"],"latest_commit_sha":null,"homepage":"https://prisma-nextjs-blog.vercel.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/prisma.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2022-04-08T15:54:30.000Z","updated_at":"2025-04-02T08:22:33.000Z","dependencies_parsed_at":"2023-10-02T15:01:21.199Z","dependency_job_id":"47cf7fd0-aecb-476e-aa59-0fe5578dec84","html_url":"https://github.com/prisma/fullstack-prisma-nextjs-blog","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prisma%2Ffullstack-prisma-nextjs-blog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prisma%2Ffullstack-prisma-nextjs-blog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prisma%2Ffullstack-prisma-nextjs-blog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prisma%2Ffullstack-prisma-nextjs-blog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/prisma","download_url":"https://codeload.github.com/prisma/fullstack-prisma-nextjs-blog/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247332556,"owners_count":20921853,"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":["nextjs","postgres","prisma"],"created_at":"2024-11-11T18:15:51.794Z","updated_at":"2025-04-05T12:01:45.093Z","avatar_url":"https://github.com/prisma.png","language":"TypeScript","readme":"# Fullstack Authentication Example with Next.js and NextAuth.js\n\nWith Railway Integration\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fprisma%2Ffullstack-prisma-nextjs-blog\u0026env=SECRET,GITHUB_ID,GITHUB_SECRET\u0026project-name=fullstack-prisma-nextjs-blog\u0026repo-name=fullstack-prisma-nextjs-blog\u0026integration-ids=oac_eGEyJUf8jDjOQSCNJiyYRbfX)\n\nWithout the Railway integration\n\n[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fprisma%2Ffullstack-prisma-nextjs-blog\u0026env=DATABASE_URL,SECRET,GITHUB_ID,GITHUB_SECRET\u0026project-name=fullstack-prisma-nextjs-blog\u0026repo-name=fullstack-prisma-nextjs-blog)\n\nThis is a starter that shows how to implement a **fullstack app in TypeScript with [Next.js](https://nextjs.org/)** with the following stack:\n\n- [React](https://reactjs.org/) (frontend)\n- [Next.js API routes](https://nextjs.org/docs/api-routes/introduction)\n- [Prisma Client](https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client) (backend).\n- [NextAuth.js](https://next-auth.js.org/) for authentication. \n- [PostgreSQL](http://postgresql.org/) as the database of choice.\n\nBefore you deploy the application to Vercel, ensure you\n- (Optional) Sign in to Railway and create a PostgreSQL database\n- Create a separate GitHub OAuth application before you deploy your application\n- Update the **Authorization callback URL** with the URL of the deployed app after successfully deploying the app\n\nNote that the app uses a mix of server-side rendering with `getServerSideProps` (SSR) and static site generation with `getStaticProps` (SSG). When possible, SSG is used to make database queries already at build-time (e.g. when fetching the [public feed](./pages/index.tsx)). Sometimes, the user requesting data needs to be authenticated, so SSR is being used to render data dynamically on the server-side (e.g. when viewing a user's [drafts](./pages/drafts.tsx)).\n\n## Getting started\n\n### 1. Download and install dependencies\n\nClone this repository:\n\n```\ngit clone git@github.com:prisma/prisma-nextjs-blog.git\n```\n\nInstall npm dependencies:\n\n```\ncd prisma-nextjs-blog\nnpm install\n```\n\n\u003c/details\u003e\n\n### 2. Create and seed the database\n\nIf you're using Docker on your computer, the following script to set up PostgreSQL database using the `docker-compose.yml` file at the root of your project:\n\n```\nnpm run db:up\n```\n\nRun the following command to create your PostgreSQL database. This also creates the `User`, `Post`, `Account`, `Session` and `VerificationToken` tables that are defined in [`prisma/schema.prisma`](./prisma/schema.prisma):\n\n```\nnpx prisma migrate dev --name init\n```\n\nWhen `npx prisma migrate dev` is executed against a newly created database, seeding is also triggered. The seed file in [`prisma/seed.ts`](./prisma/seed.ts) will be executed and your database will be populated with the sample data.\n\n\n### 3. Configuring your authentication provider\n\nIn order to get this example to work, you need to configure the [GitHub](https://next-auth.js.org/providers/github) authentication provider from NextAuth.js.\n\n#### Configuring the GitHub authentication provider\n\n\u003cdetails\u003e\u003csummary\u003eExpand to learn how you can configure the GitHub authentication provider\u003c/summary\u003e\n\nFirst, log into your [GitHub](https://github.com/) account.\n\nThen, navigate to [**Settings**](https://github.com/settings/profile), then open to [**Developer Settings**](https://github.com/settings/apps), then switch to [**OAuth Apps**](https://github.com/settings/developers).\n\n![](https://res.cloudinary.com/practicaldev/image/fetch/s--fBiGBXbE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/4eQrMAs.png)\n\nClicking on the **Register a new application** button will redirect you to a registration form to fill out some information for your app. The **Authorization callback URL** should be the Next.js `/api/auth` route.\n\nAn important thing to note here is that the **Authorization callback URL** field only supports a single URL, unlike e.g. Auth0, which allows you to add additional callback URLs separated with a comma. This means if you want to deploy your app later with a production URL, you will need to set up a new GitHub OAuth app.\n\n![](https://res.cloudinary.com/practicaldev/image/fetch/s--v7s0OEs_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://i.imgur.com/tYtq5fd.png)\n\nClick on the **Register application** button, and then you will be able to find your newly generated **Client ID** and **Client Secret**. Copy and paste this info into the [`.env`](./env) file in the root directory.\n\nThe resulting section in the `.env` file might look like this:\n\n```\n# GitHub oAuth\nGITHUB_ID=6bafeb321963449bdf51\nGITHUB_SECRET=509298c32faa283f28679ad6de6f86b2472e1bff\n```\n\n\u003c/details\u003e\n\n\n### 4. Start the app\n\n```\nnpm run dev\n```\n\nThe app is now running, navigate to [`http://localhost:3000/`](http://localhost:3000/) in your browser to explore its UI.\n\n## Evolving the app\n\nEvolving the application typically requires three steps:\n\n1. Migrate your database using Prisma Migrate\n1. Update your server-side application code\n1. Build new UI features in React\n\nFor the following example scenario, assume you want to add a \"profile\" feature to the app where users can create a profile and write a short bio about themselves.\n\n### 1. Migrate your database using Prisma Migrate\n\nThe first step is to add a new table, e.g. called `Profile`, to the database. You can do this by adding a new model to your [Prisma schema file](./prisma/schema.prisma) file and then running a migration afterwards:\n\n```diff\n// schema.prisma\n\nmodel Post {\n  id        Int     @default(autoincrement()) @id\n  title     String\n  content   String?\n  published Boolean @default(false)\n  author    User?   @relation(fields: [authorId], references: [id])\n  authorId  Int\n}\n\nmodel User {\n  id      Int      @default(autoincrement()) @id \n  name    String? \n  email   String   @unique\n  posts   Post[]\n+ profile Profile?\n}\n\n+model Profile {\n+  id     Int     @default(autoincrement()) @id\n+  bio    String?\n+  userId Int     @unique\n+  user   User    @relation(fields: [userId], references: [id])\n+}\n```\n\nOnce you've updated your data model, you can execute the changes against your database with the following command:\n\n```\nnpx prisma migrate dev\n```\n\n### 2. Update your application code\n\nYou can now use your `PrismaClient` instance to perform operations against the new `Profile` table. Here are some examples:\n\n#### Create a new profile for an existing user\n\n```ts\nconst profile = await prisma.profile.create({\n  data: {\n    bio: \"Hello World\",\n    user: {\n      connect: { email: \"alice@prisma.io\" },\n    },\n  },\n});\n```\n\n#### Create a new user with a new profile\n\n```ts\nconst user = await prisma.user.create({\n  data: {\n    email: \"john@prisma.io\",\n    name: \"John\",\n    profile: {\n      create: {\n        bio: \"Hello World\",\n      },\n    },\n  },\n});\n```\n\n#### Update the profile of an existing user\n\n```ts\nconst userWithUpdatedProfile = await prisma.user.update({\n  where: { email: \"alice@prisma.io\" },\n  data: {\n    profile: {\n      update: {\n        bio: \"Hello Friends\",\n      },\n    },\n  },\n});\n```\n\n\n### 3. Build new UI features in React\n\nOnce you have added a new endpoint to the API (e.g. `/api/profile` with `/POST`, `/PUT` and `GET` operations), you can start building a new UI component in React. It could e.g. be called `profile.tsx` and would be located in the `pages` directory.\n\nIn the application code, you can access the new endpoint via `fetch` operations and populate the UI with the data you receive from the API calls.\n\n\n## Switch to another database (e.g. PostgreSQL, MySQL, SQL Server, MongoDB)\n\nIf you want to try this example with another database than SQLite, you can adjust the the database connection in [`prisma/schema.prisma`](./prisma/schema.prisma) by reconfiguring the `datasource` block. \n\nLearn more about the different connection configurations in the [docs](https://www.prisma.io/docs/reference/database-reference/connection-urls).\n\n\u003cdetails\u003e\u003csummary\u003eExpand for an overview of example configurations with different databases\u003c/summary\u003e\n\n### PostgreSQL\n\nFor PostgreSQL, the connection URL has the following structure:\n\n```prisma\ndatasource db {\n  provider = \"postgresql\"\n  url      = \"postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA\"\n}\n```\n\nHere is an example connection string with a local PostgreSQL database:\n\n```prisma\ndatasource db {\n  provider = \"postgresql\"\n  url      = \"postgresql://janedoe:mypassword@localhost:5432/notesapi?schema=public\"\n}\n```\n\n### MySQL\n\nFor MySQL, the connection URL has the following structure:\n\n```prisma\ndatasource db {\n  provider = \"mysql\"\n  url      = \"mysql://USER:PASSWORD@HOST:PORT/DATABASE\"\n}\n```\n\nHere is an example connection string with a local MySQL database:\n\n```prisma\ndatasource db {\n  provider = \"mysql\"\n  url      = \"mysql://janedoe:mypassword@localhost:3306/notesapi\"\n}\n```\n\n### Microsoft SQL Server\n\nHere is an example connection string with a local Microsoft SQL Server database:\n\n```prisma\ndatasource db {\n  provider = \"sqlserver\"\n  url      = \"sqlserver://localhost:1433;initial catalog=sample;user=sa;password=mypassword;\"\n}\n```\n\n### MongoDB\n\nHere is an example connection string with a local MongoDB database:\n\n```prisma\ndatasource db {\n  provider = \"mongodb\"\n  url      = \"mongodb://USERNAME:PASSWORD@HOST/DATABASE?authSource=admin\u0026retryWrites=true\u0026w=majority\"\n}\n```\nBecause MongoDB is currently in [Preview](https://www.prisma.io/docs/about/releases#preview), you need to specify the `previewFeatures` on your `generator` block:\n\n```\ngenerator client {\n  provider        = \"prisma-client-js\"\n  previewFeatures = [\"mongodb\"]\n}\n```\n\u003c/details\u003e\n\n## Next steps\n\n- Check out the [Prisma docs](https://www.prisma.io/docs)\n- Share your feedback in the [Prisma Discord](https://pris.ly/discord/)\n- Create issues and ask questions on [GitHub](https://github.com/prisma/prisma/)\n- Watch our biweekly \"What's new in Prisma\" livestreams on [Youtube](https://www.youtube.com/channel/UCptAHlN1gdwD89tFM3ENb6w)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprisma%2Ffullstack-prisma-nextjs-blog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprisma%2Ffullstack-prisma-nextjs-blog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprisma%2Ffullstack-prisma-nextjs-blog/lists"}