Build a React Twitter Clone Using Prisma and Next.js

The best way to learn a tool like React is to build something with it. Next.js is a powerful framework that helps you build for production. In this tutorial, we’ll learn how to build a clone of Twitter using Next.js and Prisma.

Our app will have the following features:

  • authentication using NextAuth and Twitter OAuth
  • an option to add a new tweet
  • an option to view a list of tweets
  • an option to view the profile of a user with only their tweets

The code for the app we’ll be building is available on GitHub. We’ll be using TypeScript to build our app.

Preliminaries

Next.js is one of the most popular React.js frameworks. It has a lot of features like server-side rendering, TypeScript support, image optimization, I18n support, file-system routing, and more.

Prisma is an ORM for Node.js and TypeScript. It also provides a lot of features like raw database access, seamless relation API, native database types, and so on.

Software required

We’ll need the following installed for the purposes of running our app:

  • Docker
  • npm
  • yarn
  • git

These technologies will be used in the app:

  • Next.js: for building our app
  • Prisma: for fetching and saving data into the database
  • Chakra UI: for adding styles to our app
  • NextAuth: for handling authentication
  • React Query: for fetching and updating data in our app

Creating a new Next.js App

Now, let’s get started! We’ll first create a new Next.js app by running the following command from our terminal:

yarn create next-app 

We’ll need to enter the name of the app when the command prompts for it. We can name it anything we want. However, in this case, I’ll name it twitter-clone. We should be able to see a similar output on our terminal:

$ yarn create next-app yarn create v1.22.5 [1/4] ???? Resolving packages... [2/4] ???? Fetching packages... [3/4] ???? Linking dependencies... [4/4] ???? Building fresh packages... success Installed "create-next-app@10.0.4" with binaries: - create-next-app ✔ What is your project named? twitter-clone Creating a new Next.js app in /twitter-clone. .... Initialized a git repository. Success! Created twitter-clone at /twitter-clone Inside that directory, you can run several commands: yarn dev Starts the development server. yarn build Builds the app for production. yarn start Runs the built app in production mode. We suggest that you begin by typing: cd twitter-clone yarn dev 

We can now go inside the twitter-clone directory and start our app by running the following command:

cd twitter-clone && yarn dev 

Our Next.js app should be up and running on http://localhost:3000. We should be able to see the following screen:

Next.js app running on localhost:3000

Adding a Dockerized PostgreSQL Database

Next, let’s add a Dockerized PostgreSQL database so that we can save the users and tweets into it. We can create a new docker-compose.yml file in the root of our app with the following content:

version: "3" services: db: container_name: db image: postgres:11.3-alpine ports: - "5432:5432" volumes: - db_data:/var/lib/postgresql/data restart: unless-stopped volumes: db_data: 

If Docker is running on our machine, we can execute the following command from the root of our app to start our PostgreSQL container:

docker-compose up 

The above command will start the PostgreSQL container and it can be accessed on postgresql://postgres:@localhost:5432/postgres. Note that you can also use a local installation of Postgres instead of a Dockerized one.

Adding Chakra UI

Chakra UI is a very simple React.js component library. It’s very popular and has the features like accessibility, support for both light and dark mode, and more. We’ll be using Chakra UI for styling our user interface. We can install that package by running the following command from the root of our app:

yarn add @chakra-ui/react @emotion/react @emotion/styled framer-motion 

Let’s rename our _app.js file to _app.tsx inside the pages directory and replace its content with the following:

// pages/_app.tsx import { ChakraProvider } from "@chakra-ui/react"; import { AppProps } from "next/app"; import Head from "next/head"; import React from "react"; const App = ({ Component, pageProps }: AppProps) => { return ( <> <Head> <link rel="shortcut icon" href="/images/favicon.ico" /> </Head> <ChakraProvider> <Component {...pageProps} /> </ChakraProvider> </> ); }; export default App; 

Since we added a new TypeScript file, we’ll need to restart our Next.js server. Once we restart our server, we’ll get the following error:

$ yarn dev yarn run v1.22.5 $ next dev ready - started server on http://localhost:3000 It looks like you're trying to use TypeScript but do not have the required package(s) installed. Please install typescript, @types/react, and @types/node by running: yarn add --dev typescript @types/react @types/node If you are not trying to use TypeScript, please remove the tsconfig.json file from your package root (and any TypeScript files in your pages directory). 

This is because we added a new TypeScript file but didn’t add the necessary dependencies that are required to run them. We can fix that by installing the missing dependencies. From the root of our app, we can execute the following command to install the missing dependencies:

yarn add --dev typescript @types/react @types/node 

Now, if we start our Next.js server, our app should compile:

$ yarn dev yarn run v1.22.5 $ next dev ready - started server on http://localhost:3000 We detected TypeScript in your project and created a tsconfig.json file for you. event - compiled successfully 

Adding NextAuth

NextAuth is an authentication library for Next.js. It’s simple and easy to understand, flexible and secure by default. To set up NextAuth in our app, we’ll need to install it by running the following command from the root of our app:

yarn add next-auth 

Next, we’ll have to update our pages/_app.tsx file with the following content:

// pages/_app.tsx import { ChakraProvider } from "@chakra-ui/react"; import { Provider as NextAuthProvider } from "next-auth/client"; import { AppProps } from "next/app"; import Head from "next/head"; import React from "react"; const App = ({ Component, pageProps }: AppProps) => { return ( <> <Head> <link rel="shortcut icon" href="/images/favicon.ico" /> </Head> <NextAuthProvider session={pageProps.session}> <ChakraProvider> <Component {...pageProps} /> </ChakraProvider> </NextAuthProvider> </> ); }; export default App; 

Here, we’re wrapping our app with NextAuthProvider. Next, we’ll have to create a new file named [...nextauth].ts inside the pages/api/auth directory with the following content:

// pages/api/auth/[...nextauth].ts import { NextApiRequest, NextApiResponse } from "next"; import NextAuth from "next-auth"; import Providers from "next-auth/providers"; const options = { providers: [ Providers.Twitter({ clientId: process.env.TWITTER_KEY, clientSecret: process.env.TWITTER_SECRET, }), ], }; export default NextAuth(options); 

The above file will be responsible for handling our authentication using Next.js API routes. Next, we’ll create a new filed named .env in the root of our app to store all our environment variables with the following content:

DATABASE_URL="postgresql://postgres:@localhost:5432/postgres?synchronize=true" NEXTAUTH_URL=http://localhost:3000 NEXT_PUBLIC_API_URL=http://localhost:3000 TWITTER_KEY="" TWITTER_SECRET="" 

The Twitter environment variables will be generated from the Twitter API. We’ll be doing that next. We can create a new Twitter app from the Twitter Developer dashboard.

  1. Create a new Twitter app by entering its name and click on the Complete button.

    Create a new Twitter app

  2. Copy the API key, API secret key and Bearer token in the next screen.

    The credentials of our Twitter app

  3. Change the App permissions from Read Only to Read and Write in the next screen.

    Twitter app permissions

  4. Click on the Edit button next to the Authentication settings to enable 3-legged OAuth.

    Authentication settings for our Twitter app

  5. Enable 3-legged OAuth and Request email address from users and add http://localhost:3000/api/auth/callback/twitter as a Callback URL.

    Edit the authentication settings of our Twitter app

  6. The Website URL, Terms of service and Privacy policy files can be anything (such as https://yourwebsite.com, https://yourwebsite.com/terms and https://yourwebsite.com/privacy respectively).

Our 3-legged OAuth should be enabled now.

Enable the 3-legged OAuth of our Twitter app

Paste the value of the API key from Step 2 into the TWITTER_KEY environment variable and the value of API secret key into the TWITTER_SECRET environment variable.

Our .env file should look like this now:

DATABASE_URL="postgresql://postgres:@localhost:5432/postgres" NEXTAUTH_URL=http://localhost:3000 NEXT_PUBLIC_API_URL=http://localhost:3000 TWITTER_KEY="1234" // Replace this with your own API key TWITTER_SECRET="secret" // Replaces this with your own API secret key 

Now, if we restart our Next.js server and visit http://localhost:3000/api/auth/signin, we should be able to see the Sign in with Twitter button:

Sign in with Twitter button

If we click on that button, we’ll be able to authorize our Twitter app but we won’t be able to log in to our app. Our terminal will show the following error:

[next-auth][warn][jwt_auto_generated_signing_key] https://next-auth.js.org/warnings#jwt_auto_generated_signing_key 

We’ll fix this issue next when we’ll be adding and configuring Prisma.

Continue reading Build a Twitter Clone Using TypeScript, Prisma and Next.js on SitePoint.

Similar Posts