Here is a tutorial on how to build sign in and sign up pages and store the user in a context in a Next.js app.
If you want you can clone this repo to get the code for the tutorial:
git clone https://github.com/JIdayyy/authentication-next-typescript
cd authentication-next-typescript
npm install
npm run dev
Then you need to create a folder in the pages folder called auth and create two files in it called signin.tsx and signup.tsx.
In those pages we will create two forms, one for signing in and one for signing up. We will also create a context to store the user in.
Context.
The idea here is to create a context that will store the user and provide it to the rest of the app. We will use the useContext hook to access the user.
First, create the src folder and inside it create a folder called context and inside it create a file called UserContext.tsx.
In this file you will create the UserContext.
First, import the method createContext from React and create the user context.
As you know, we use Typescript so we have to create a type for our context.
In the same file create an interface IUserContext and a User type like below:
As you can see our interface have 4 keys, one containing the User one is a boolean wich will be true/false if the user is connected or not and two methods signIn & signOut wich will handle the API call, the token logic and set the user state.
The User type basically represent our User.
When those types are good, we need to type our context like this :
type TUserContextProviderProps={children: React.ReactNode;};constUserContextProvider=({ children }: TUserContextProviderProps)=>{return<UserContext.Provider>{children}</UserContext.Provider>;};
This component will handle all the logic of our authentication flow.
We will create a state inside with two keys, isAuth and user.
type AuthState={user: TUser|null;isAuth: boolean;};constUserContextProvider=({ children }: TUserContextProviderProps)=>{const[authState,setAuthState]=useState<AuthState>({user: null,isAuth: false,});return<UserContext.Provider>{children}</UserContext.Provider>;};
Good, now we have our state in the provider, we have now to create the signIn and signOut methods to authenticate our users.
In a separate files create an instance of axios like this :
This function make a post request to our signin endpoint, set the user in the response body in our state and pass the isAuth key at true.
Here the jwt token is in the authorization header, so we get it from the axios response headers and set it in the local storage.
For the signOut method it is way more simple, the function simply set the user state key as null and the isAuth key as false and remove the token from the local storage.
To consume this context I use to create a custom hook in the same file like this :
// src/context/userContext.tsx
exportconstuseAuth=()=>{constcontext=useContext(UserContext);if(context===null){thrownewError("useAuth must be used within a UserContextProvider");}returncontext;};
As you can see we use the useContext hook to get the context and throw an error if the context is null.
With this hook we can use the context in our components like this :
I know there is a lot of informations here, but in the end it is not that complicated to implement a context in your nextjs app and it is really useful to manage your user state.
Once you have done this you can use the context in all your components and pages to get the user informations like the email or avatar.
The token is also stored in the localStorage so you can use it to make authenticated requests to your backend.