Next.js Protected Routes: Require User Profiles with Kinde (EASY!)

James Q Quick
10 Apr 202425:32

Summary

TLDRThis video script outlines the process of user onboarding for an application, focusing on the 'Potl Pal' example. It details the importance of collecting complete user profiles post-sign up and demonstrates gating access to certain pages until profiles are fully created. The script covers technical implementations using Next.js, Auth0 for authentication, and Zeta for database management, highlighting the setup of a multi-step form and the significance of required user information like names and usernames for event participation.

Takeaways

  • 📝 The video discusses the process of user onboarding in an application called 'Potl Pal', focusing on gating access to certain pages until the user completes their profile after signup.
  • 🔒 It emphasizes the importance of collecting essential information like name and username for adding people to events, which is why the rest of the pages are gated until the profile is complete.
  • 🔄 The presenter demonstrates the use of Next.js 14 with the App Router for routing and the use of K for authentication, which is a sponsor of the video.
  • 🗃️ The video mentions the use of Zeta as the database to store user profile information separately from the authentication data stored in K.
  • 🛠️ The presenter shows the setup process in K, including creating a new application and configuring environment variables for authentication callbacks and logout URLs.
  • 🔑 The video covers the technical setup required for authentication, including setting up API routes in Next.js to handle login and logout processes with K.
  • 🔍 It also discusses the implementation of a loading indicator to check username availability, which is a feature the presenter considers highlighting in a separate video.
  • 📝 The script talks about the importance of making the signup process easy and only requiring essential information upfront, with the option to fill out smaller details later.
  • 🔄 The video includes a walkthrough of the code setup for the application, including environment variable configuration and the use of the K SDK for authentication.
  • 📚 The presenter mentions the possibility of creating a mini-course based on the application, indicating an interest in expanding on the content covered in the video.
  • 🔗 The video concludes with an invitation for viewers to subscribe to the presenter's newsletter for updates on the mini-course and other content.

Q & A

  • What is the purpose of the 'Potl Pal' application mentioned in the script?

    -The 'Potl Pal' application is designed to facilitate user sign-ups and manage events where users can add their names and request others to bring items. It emphasizes creating a full profile post sign-up to ensure smooth event management.

  • How does the sign-in process work in the 'Potl Pal' application?

    -The sign-in process involves using an email to receive a confirmation code, which the user then enters to be redirected back to the application. This initiates the profile completion stage, which is essential for further interaction within the app.

  • Why is gating access to certain pages until the user completes their profile important in the 'Potl Pal' application?

    -Gating access ensures that users add essential information like their name and username, which is crucial for adding people to events or requesting items. This process streamlines the user experience and functionality within the app.

  • What is the role of the loading indicator feature in the 'Potl Pal' application?

    -The loading indicator is a neat feature that checks the availability of a username. It provides real-time feedback to the user during the profile creation process, enhancing the user interface and experience.

  • How is user authentication handled in the 'Potl Pal' application?

    -User authentication is managed through a combination of Next.js 14 with the App Router and K for authentication. K is used to handle login and logout processes, and it integrates with Next.js to manage user sessions effectively.

  • What is the significance of using Zeta as a database for the 'Potl Pal' application?

    -Zeta is used as a database to store user profiles separately from the authentication data managed by K. It allows for the storage of additional user information, such as names and usernames, which are essential for the app's functionality.

  • How does the 'Potl Pal' application ensure that users complete their profiles before accessing other features?

    -The application uses a redirect mechanism that sends users back to the profile completion page if they attempt to access features like 'My Events' or 'Create an Event' without having completed their profiles.

  • What is the role of the 'useKindBrowserClient' hook in the 'Potl Pal' application?

    -The 'useKindBrowserClient' hook is used to access the user object and loading state from the K authentication client. It helps in determining whether a user is logged in and provides the necessary user information for the application.

  • How does the 'Potl Pal' application manage the sign-up process to make it as easy as possible?

    -The application simplifies the sign-up process by initially requiring only an email for sign-up. It then focuses on collecting additional necessary information like name and username post sign-up to complete the user profile.

  • What are the considerations for storing additional user properties in the 'Potl Pal' application?

    -The application considers whether to store additional user properties within K or in a separate database like Zeta. The decision is based on convenience, control, and how the data will be accessed in relation to other application data.

  • How does the 'Potl Pal' application handle the creation of user profiles in Zeta?

    -The application uses the Zeta TypeScript SDK to interact with the Zeta database. It creates a user profile table and stores user information such as the user ID, username, and actual name, ensuring each profile is unique and associated with the correct user.

Outlines

00:00

📝 User Onboarding and Profile Completion in Potl Pal App

The video script discusses the user onboarding process for a sign-up application, using 'Potl Pal' as an example. It explains the importance of obtaining additional user information post-registration to create a full profile. The speaker details the process of signing in with an email and receiving a confirmation code, which then redirects the user to complete their profile by adding a name and username, essential for event participation. The script also mentions gating pages to ensure profile completion before allowing access to other features like 'My Events' or 'Create an Event'. A unique feature to check username availability is highlighted, and the use of Next.js with the app router, K for authentication, and Zeta for the database is outlined, emphasizing the complexity of creating a multi-step form.

05:00

🔧 Setting Up Authentication with K and Environment Variables

This paragraph delves into the technical setup for authentication using K, a sponsor of the video. It covers creating a new application in K, setting up callback and logout URLs, and configuring environment variables within the project. The process of setting up a dynamic route for handling different API endpoints like login and logout is explained. The paragraph also touches on the use of the K OSS Next.js package for integrating authentication into the Next.js application, including the necessary steps to ensure K can redirect successfully and the importance of updating URLs once the application is deployed.

10:02

📱 Integrating K Authentication Components and User Checks

The script continues with the implementation of K authentication components, such as the login and logout links, and a hook for accessing the user state and loading status. It describes the process of importing these components from the K OSS Next.js package and using them within the application's navbar. The importance of only displaying certain navbar links to logged-in users is emphasized, and the script provides a walkthrough of checking if a user is logged in and not loading, showing the sign-in link accordingly. It also mentions the possibility of expanding on the sign-in process with additional videos.

15:02

🗂️ Storing User Profiles in Zeta Database and Redirection Logic

The paragraph explains the decision to store user profiles in a Zeta database, separate from the K authentication process. It details the creation of a new database and a user profile table within Zeta, with unique fields for user ID, username, and actual name. The script outlines the process of setting up the Zeta client in the application, including logging in, selecting the project, and generating the necessary API key and database references. It also discusses the logic for checking if a user profile exists and the redirection to the 'Create Profile' page if it does not, as well as the use of typescript for better code inference and safety.

20:03

🛠️ Implementing Redirection for Incomplete User Profiles

This section focuses on the implementation of redirection logic to ensure that users are directed to create their profiles if they haven't done so already. It describes the process of checking for a user profile upon accessing the dashboard and other related pages, and the use of Next.js' redirect function for this purpose. The script also explains the logic for checking the existence of a user profile before allowing access to the 'Create Profile' page, to prevent users from accessing it if they already have a profile. The importance of placing these checks within a layout component in Next.js to streamline the process across multiple pages is highlighted.

25:05

🎓 Conclusion and Future Learning Opportunities

The final paragraph wraps up the video script by summarizing the onboarding workflow process discussed using Next.js 14 and other associated technologies. It hints at the possibility of turning the content into a mini-course and invites viewers to subscribe to the creator's newsletter for updates. The script concludes by expressing hope that the video was informative and bids farewell to the viewers until the next video.

Mindmap

Keywords

💡Onboarding

Onboarding refers to the process of integrating new users into an application, ensuring they have a clear understanding of how to use it. In the video, onboarding is crucial for the 'Potl Pal' application, as it guides new users to complete their profile with essential information like name and username, which are required for participating in events.

💡Profile Completion

Profile Completion is the act of filling out all necessary information in a user's profile. In the context of the video, it is a gating mechanism to ensure that users add a name and a username before they can access other parts of the application, like creating or joining events.

💡Next.js

Next.js is a JavaScript framework for building user interfaces. The video discusses using Next.js 14 with the app router for handling the routing and navigation of the 'Potl Pal' application, including the redirection after login and profile completion.

💡Authentication

Authentication is the process of verifying the identity of a user. The video script mentions using K (an authentication service) for managing user sign-in and sign-out processes, which is essential for securing the application and ensuring that only authenticated users can access certain features.

💡Database

A database is a structured collection of data. In the video, Zeta is used as the database to store user profiles, separate from the authentication data stored in K. The script describes how user profile information is saved in Zeta after being entered in the application.

💡Environment Variables

Environment variables are used to set configuration settings for an application. The script explains how to set environment variables for the K authentication service, including client ID, client secret, issuer URL, and redirect URLs, which are essential for the authentication process.

💡User Experience (UX)

User Experience (UX) refers to how a person feels when interacting with a system. The video focuses on improving the UX by creating a smooth onboarding process, using features like loading indicators and multi-step forms to enhance the user's journey through the application.

💡Multi-Step Form

A multi-step form is a form that is divided into multiple screens or steps. The video script discusses the complexity of creating a multi-step form for event creation in the 'Potl Pal' application, which is part of the user's journey after completing their profile.

💡Redirection

Redirection is the process of sending a user from one URL to another. The video script mentions several instances of redirection, such as after a user logs in or attempts to access a page before completing their profile, to ensure a seamless user flow.

💡Server Components

Server Components in Next.js are a way to render components on the server, which can improve performance and SEO. The script refers to the use of server components in Next.js 14 for handling data fetching and rendering, which is part of the application's architecture.

💡TypeScript

TypeScript is a programming language that is a superset of JavaScript, adding static types for better code reliability. The video script mentions using TypeScript for the Zeta database SDK, which helps in generating types for the database operations and improves the development experience.

Highlights

Creating a user onboarding process for 'Potl Pal' application to ensure users complete their profile after sign-up.

Utilizing email confirmation codes for initial user sign-in to the application.

Gating access to other pages until users add essential information such as name and username.

Implementing a loading indicator to check username availability in real-time.

Using Next.js 14 with the App Router for front-end development.

Incorporating K for authentication, which is also the sponsor of the video.

Storing user profile data in Zeta, a separate database from the authentication provider.

Discussing the importance of separating user login information from additional profile data.

Creating dynamic API routes in Next.js for handling authentication endpoints.

Demonstrating the setup of environment variables for authentication with K.

Integrating the K authentication SDK with Next.js for seamless user login and logout.

Using the useKindBrowserClient hook to access user data and loading state.

Designing a multi-step form for event creation with user profile completion as a prerequisite.

Exploring the debate on the best practices for user onboarding and profile completion.

Implementing conditional rendering in the navbar based on user authentication state.

Creating a seamless user experience by redirecting users appropriately post-login.

Considering the use of social providers for authentication alongside email-based methods.

Using Zeta's TypeScript SDK for database interactions and leveraging its auto-generated types.

Discussing the use of layouts in Next.js to manage access control across multiple pages.

Providing insights on user data requirements and the importance of not overburdening new users with optional information.

Considering the creation of a mini-course to guide users through building the application from the video.

Transcripts

play00:00

often times when we have user sign up

play00:02

for application there's actually more

play00:03

information that we want from them after

play00:05

sign up to create a full profile for

play00:07

example so this is an example I've been

play00:10

working on called potl pal with a few of

play00:12

my partners Technologies and you go

play00:14

through the process to sign in and I can

play00:16

use my email and it will send me a

play00:19

confirmation code that I can enter in

play00:21

here this will redirect me back to the

play00:23

application and at this point I want the

play00:25

user to complete their profile so I

play00:27

actually gate the rest of these pages to

play00:29

make sure that they finish adding a name

play00:31

and a username because this is going to

play00:33

be essential for how we add people to an

play00:35

event or request that people bring

play00:37

things in this example so you can tell

play00:39

if I go to the my events tab this is

play00:41

going to redirect back to the profile

play00:43

tab if I go to create an event it

play00:44

redirects back here as well so we want

play00:46

to make sure that users have their

play00:47

profile created before we allow them to

play00:50

get through now inside of here I also

play00:51

have a neat little feature that I might

play00:53

do a separate video on kind of this

play00:54

loading indicator to choose whether or

play00:56

not a um a username is available that I

play01:00

think is pretty cool so after we create

play01:02

this profile what this will do is save

play01:04

this in the database and then we'd be

play01:05

able to come over to the form for

play01:07

creating an event as well so I'll

play01:09

probably have a few additional videos on

play01:11

how to create this multi-step form which

play01:12

I found to be very complicated to be

play01:14

quite honest uh but I want to focus on

play01:16

the user profile and onboarding

play01:18

experience so basically the idea of

play01:19

letting a user sign up but then also

play01:21

gating Pages until they finish the

play01:23

necessary information that you want now

play01:25

you'll find some mixed reviews on how

play01:27

exactly this should work typically what

play01:29

people agree on on is you should make

play01:30

the sign up process as easy as possible

play01:33

and then you should let some of the

play01:35

smaller details get figured out later if

play01:37

they're not necessary in this case since

play01:39

we need to have those profile pieces of

play01:41

information the name and the username

play01:43

we're going to make those required but

play01:44

we'll let the signup process happen with

play01:46

just email using kind and then take over

play01:49

the user profile information associated

play01:52

with that user after that so what we're

play01:54

going to use is next js14 with the app

play01:57

router I've actually got a demo project

play01:58

set up that I'll show you in a second

play01:59

and then we're going to use K for

play02:01

authentication K is actually the sponsor

play02:02

of this video so the first time working

play02:04

with K but it's worked really well as

play02:06

we'd expect inside of nextjs you'll see

play02:08

that in a second and then uh Zeta for a

play02:10

database to actually store the user

play02:12

profile and we'll talk about why that's

play02:13

separate from the actual user in kind in

play02:15

a minute so let's take a look at the

play02:18

starter code that I have or actually

play02:21

probably be easier to uh just show you

play02:23

this running so this is running at Local

play02:25

Host 3001 and I basically have a copy of

play02:29

the front end uh design which I think

play02:31

these cards are pretty cool and then

play02:32

what we're going to do is come in and

play02:34

add the signin functionality and then

play02:35

we're going to add all the other

play02:36

functionality for the user profile and

play02:38

then we'll actually save that

play02:39

information into our database so the

play02:41

first thing we'll want to do is go into

play02:44

kind and you can log in for a free

play02:46

account so I'll go ahead and log in with

play02:48

my GitHub account and after you've

play02:50

logged in you'll be taken to your

play02:51

dashboard you can see I basically have

play02:53

one application here which is what I've

play02:54

been working on with potl pal so I'm

play02:56

going to add a completely brand new

play02:58

application and we'll call this user

play03:00

profile demo this will be considered a

play03:04

backend web application so we'll go

play03:06

ahead and create that and then inside of

play03:08

here we're going to create a nextjs um

play03:10

project so it's interesting that this is

play03:12

referenced as backend uh interesting

play03:15

because nextjs can do front end and

play03:17

backend and actually doing

play03:18

authentication on the front end and the

play03:20

backend is actually a pretty tricky

play03:21

topic but I'm going to choose nextjs in

play03:23

here and then we'll uh save this and

play03:26

this will give us a couple of different

play03:28

uh properties that we can use

play03:30

you should actually just press set on

play03:31

both of those variables but we'll come

play03:33

back and fix that in a minute so I'm

play03:34

going to copy the Callback URL and the

play03:37

logout URL basically where do we want to

play03:39

send the user uh with the call back

play03:42

after they logged in and then where do

play03:43

we want to send the user after they've

play03:44

logged out they have a starter kit we're

play03:46

going to start from scratch here which

play03:47

is okay uh and then I'm just going to

play03:49

copy all of these uh into my environment

play03:52

variable file so a couple of things that

play03:53

it has has the client ID which is the

play03:56

the ID for the specific application that

play03:58

we're creating has a client secret uh

play04:01

hidden and a copi that's nice then it

play04:02

has the issuer URL which is basically

play04:04

the domain on con that we redirect to to

play04:07

actually handle the login process have

play04:09

our site URL and then we have where do

play04:11

we want the user to go after log out and

play04:13

after login so we can copy this entire

play04:16

thing and we can create a new file

play04:19

inside of the

play04:21

root called EnV and we'll just paste all

play04:24

these credentials in so it's nice that

play04:26

they just give all these to us and then

play04:28

I'm going to go to the next xjs docs so

play04:31

that was basically the docs if you're

play04:32

starting with their uh with their

play04:34

starter code in this case we're starting

play04:36

from scratch basically so let's go ahead

play04:38

and we will install this package so the

play04:40

kind OSS kind off

play04:43

nextjs and then we'll need to copy in

play04:46

this URL to uh to be a known URL that

play04:49

they can redirect back to uh from con so

play04:52

we're going to put that in the Callback

play04:53

URLs and then we're going to put the

play04:54

Local Host 3000 in for the logout

play04:58

redirect URL now obviously these are

play05:00

URLs that you're going to need to update

play05:01

when you actually have a deployed

play05:03

application but inside of your project

play05:05

details just make sure that you save

play05:07

that so KH can actually redirect

play05:09

successfully then we have our

play05:11

environment variables we already did

play05:13

this um so we have the client ID the

play05:15

secret the issuer URL the site URL and

play05:17

then the two redirect URLs so we should

play05:20

have all the information copied uh the

play05:22

kind audience is not required this is if

play05:24

you're wanting to um confirm JWT or

play05:28

access tokens that they

play05:30

uh coming to the intended audience which

play05:32

in this case we're not getting into so

play05:34

we add all those credentials and then

play05:36

basically we have like two lines to set

play05:37

up off and this is actually really neat

play05:39

so inside of app we're going to create

play05:42

uh API SLO so inside of the app

play05:44

directory so app and then we'll have a

play05:47

new folder and we'll do API

play05:51

SLO and

play05:53

then this route name here actually could

play05:56

have copied this whole thing that's okay

play05:58

and inside of here we create a new file

play06:01

and we'll do a dynamic route uh with

play06:03

kind off in there and basically what

play06:05

this is going to do is allow uh kind

play06:08

that should be a typescript file as well

play06:10

is allow kind to handle multiple

play06:13

different API endpoints basically for

play06:15

login log out Etc which is pretty handy

play06:17

and then we will uh import the handle

play06:20

off from their package then we'll just

play06:22

export handle off and this is all it

play06:24

takes to basically have authentication

play06:26

set up inside of nextjs where we have

play06:29

environment variables and then this is

play06:31

all the configuration uh of the SDK so

play06:33

really really not too bad now we can go

play06:36

ahead and run this application just to

play06:37

make sure it's running again so let's go

play06:39

back to the running one I think this is

play06:41

on 301 301 and this should be good to go

play06:44

so nothing's changed now we can start to

play06:47

get into the navbar and I already have

play06:48

some codes stubbed out here it's

play06:50

basically just design it has the uh

play06:53

image in here it also has state for user

play06:55

and loading which we aren't really

play06:57

tracking yet now if you wanted to follow

play06:59

along with this source code you can

play07:01

actually check out the source code for

play07:02

the original project in here so I will

play07:04

make sure to push all this code all the

play07:06

original code for the poock pal demo so

play07:08

you can have this as a reference if you

play07:09

want to and I'll include a link in the

play07:10

description below but let's start with

play07:12

actually getting a reference to some

play07:14

components that we can use for login and

play07:17

log out all right so then we're going to

play07:19

import a few different things from this

play07:20

kind package now specifically we're

play07:22

going to import the login link the

play07:23

logout link and those are probably

play07:25

pretty self-explanatory and then also a

play07:28

use hook that we can use on the front

play07:30

end specifically to gain access to the

play07:32

user itself so we can actually get the

play07:34

user from that hook and a loading state

play07:36

to see whether or not we're loading

play07:38

determining whether or not we have a

play07:39

user so we're going to import all of

play07:41

these things and this is going to uh

play07:43

come from the

play07:47

kind kind OSS nextjs package and inside

play07:51

of here we're going to get the login

play07:53

link the log out link see we're getting

play07:56

good intelligence there and then the use

play07:58

kind browser CL

play08:00

now this is a little bit wordy but I

play08:01

actually like that they name this

play08:02

because nextjs authentication can be

play08:04

really tricky considering you can do

play08:06

things on the front end and the back end

play08:08

so inside of here instead of hardcoding

play08:10

these two properties user and is loading

play08:14

we can actually get these directly from

play08:16

this client so this hook use con browser

play08:19

client we can grab those two properties

play08:20

and actually reference them there so we

play08:22

can get rid of these hardcoded values

play08:24

and then we can reference them down

play08:25

below now the other thing we're going to

play08:27

do is uncomment the log out link again

play08:30

this is just log out link component that

play08:33

we put the text log out in nothing

play08:35

really we have to do there I have that

play08:36

wrapped in An Li so that it can be

play08:38

styled the way I want and the last thing

play08:40

is we'll uncomment this section which is

play08:42

basically a check to say hey if we don't

play08:44

have a user and we're not loading so we

play08:47

fully confirmed the user is not logged

play08:48

in show the sign in link or login link

play08:51

so you can call that whatever you want

play08:53

so again these two components are given

play08:55

to us we don't have to do anything for

play08:56

them other than in this case I WRA them

play08:58

with an Li so I could style them the way

play08:59

I want the last thing just to mention to

play09:01

make sure is the uh routes or the navbar

play09:05

links that are for a logged in user are

play09:06

only shown if we actually have a user

play09:08

and we're finished loading so let's say

play09:10

that let's just see what we have now I

play09:13

just restarted this application to make

play09:14

sure that this current version is

play09:16

running on Local Host 3000 I had the

play09:18

original version on 3000 but then my

play09:19

callback URLs and things were Local Host

play09:21

3000 so now I'm making sure the one that

play09:23

I'm working on is the one that I'm

play09:24

running and it is at Local Host 3000 so

play09:27

let's go and now just refresh Local Host

play09:31

3000 so we can get the current page and

play09:33

we should see there was a little bit of

play09:34

delay as it's loading to check the state

play09:36

of the logged in user you see there's no

play09:38

logged in user so now we see the sign in

play09:40

button so now we can go through and sign

play09:43

in and it says we don't have a way to

play09:44

authenticate you at the moment and this

play09:47

is because inside of our project we

play09:49

actually need to configure what type of

play09:51

authentication we're going to allow so

play09:53

in this case you can choose password

play09:55

list where they send you a code to your

play09:56

email or a password and I'm going to

play09:59

choose to do passwordless and it's worth

play10:01

noting that you can also add

play10:02

authentication for social providers as

play10:05

well so this is done at the tenant level

play10:06

so if you go back to your tenant and

play10:08

then go into settings you can come into

play10:11

authentication and then here you can see

play10:13

where you have your social connections

play10:14

and Enterprise connections that you can

play10:15

enable if you scroll through you'll see

play10:17

a bunch that you recognize Discord and

play10:19

Facebook GitHub Etc so just wanted to

play10:21

call out that there's other options that

play10:22

you can use for your login experience as

play10:24

well so by the time we come back to our

play10:28

local host and and then we click the

play10:30

sign in we should now be redirected to a

play10:32

page where we can actually go through

play10:33

this login process and I'll go through

play10:35

the same thing you saw at the beginning

play10:36

of the video while I'll grab this token

play10:38

out of my email put it in here it will

play10:40

redirect us back to the application now

play10:42

if you remember back to our onboarding

play10:43

and the environment variables that we

play10:45

copied in there was a post login

play10:47

redirect URL and this is set to/

play10:49

dashboard which is why after we log in

play10:51

it redirects us back to the actual

play10:52

dashboard route all right so I've got

play10:55

that code I'll push continue and it

play10:56

should Now take us back to the

play10:58

application in this case it's

play10:59

redirecting back to the dashboard page

play11:01

where we don't really have anything

play11:02

there yet so you can see that we have

play11:05

access to the dashboard we have no

play11:07

events yet then we also have access to

play11:09

the create an event tab but this is

play11:11

where we want to stop the user from

play11:13

getting to this place if they haven't

play11:14

actually completed their onboarding

play11:17

profile meaning their name and their

play11:19

username so in this case we want to be

play11:21

able to store this user profile inside

play11:23

of a Zeta database this is what we're

play11:25

going to use for database another

play11:27

partner of mine that I've worked a ton

play11:28

with you can see bunch of different

play11:29

Demos in here so this is completely free

play11:32

you can set up it run runs postrest

play11:34

underneath the hood I'll have more

play11:36

content actually on using this with

play11:37

Prisma in the future but for now we're

play11:39

going to use the Zeta typescript SDK so

play11:42

what we'll do is create a new database

play11:44

and we'll call this user profile demo

play11:49

and in this case I won't enable the

play11:50

direct postest although it's something

play11:52

that I would recommend doing and using

play11:53

this with Prisma it's pretty exciting

play11:55

actually that we can do this I just

play11:56

haven't updated this demo for that yet

play11:58

uh so inside of here we just want to

play12:00

have one table basically and we're going

play12:02

to have the user profile table now

play12:06

there's kind of an open question of if

play12:07

you want to store additional properties

play12:09

of a user where would you store those

play12:11

and so like other providers you actually

play12:14

have the ability to store like custom

play12:15

properties inside of kind as well but in

play12:17

this case we're going to store them in

play12:18

our own database and my thought is this

play12:21

is going to be slightly more convenient

play12:23

and wrapped around or accessed in a

play12:26

similar way that we will get all of our

play12:27

other data so kind will be the source of

play12:29

Truth for all of our uh user login

play12:32

information specifically storing

play12:34

passwords Keys tokens Etc and then we'll

play12:36

store additional information inside of

play12:38

our own database so we have complete

play12:39

control over this now the way we're

play12:41

going to do this though though is we're

play12:43

going to have the ID of the user profile

play12:45

match up with the ID of the user from

play12:48

kind that way when we get a user ID from

play12:50

the user in kind we can use that as a

play12:52

reference to pull in the user profile

play12:54

from Zeta actually I slightly misspoke

play12:57

we'll have the ID in here be

play12:58

autogenerated by Zeta and then we'll

play13:00

reference the user ID and that's what

play13:02

we're actually going to query by so

play13:04

we'll have the user ID property is a

play13:07

string and it will be unique so we'll

play13:10

make sure we'll only have one profile

play13:11

per user so we'll have the uh user user

play13:16

ID that we can do our associations with

play13:18

we'll also have the user name these will

play13:20

also be unique and then lastly we'll

play13:23

have the actual name of the user so

play13:25

we'll put that in there as well all

play13:29

right so that's all the set up in the

play13:30

database that we actually need now we

play13:32

need to actually reference this inside

play13:34

of our code so to do this we'll need to

play13:37

install The Zeta client so let's just

play13:40

take a look at the Zeta client so this

play13:42

is Zeta for typescript and JavaScript

play13:45

you can go to the details here on their

play13:48

documentation page and what we'll need

play13:50

to do is actually install that client

play13:51

but we'll also need to connect Zeta to

play13:54

our uh to our application so what we'll

play13:57

do is you would run a Zeta login for the

play14:00

first time you're uh doing this and

play14:01

it'll set up a token behind the scenes

play14:03

Etc I've already done that so I can just

play14:06

run Zeta a nit and then it's going to

play14:07

ask us basically which project do we

play14:09

want to attach this to and I want to

play14:11

attach this to the user profile demo and

play14:13

then we can add uh the Dov to the dog

play14:16

ignore it's going to ask us what sort of

play14:18

code do you want it to return in this

play14:20

case we say typescript where do we want

play14:22

that to go we can put it by default in

play14:24

source

play14:25

z.s and then what's really cool is this

play14:28

will will uh give us our API key so you

play14:31

can see reference in here it created the

play14:33

API key in ourv file and then also

play14:37

referenced a Zeta Branch as main so you

play14:39

can have multiple branches in Zeta to

play14:41

separate your uh database tables based

play14:44

on like branches or like GitHub branches

play14:46

or environments or whatever you want to

play14:48

do there the other thing that it

play14:50

generated is the

play14:58

zeta.phi data and then it uses some

play15:00

typescript inference to actually

play15:02

generate types for us that we can use

play15:04

and then lastly has a reference to the

play15:05

actual actual database itself so this is

play15:08

all pretty cool all set up for us and

play15:10

now we have a fully typed uh typescript

play15:12

SDK that we can use to interact with all

play15:14

of our data so the first thing we want

play15:17

to do is go into our dashboard page and

play15:20

notice we're not really doing anything

play15:22

inside of here so let's actually do the

play15:23

first level of a check the first check

play15:26

is just to see if we have a logged in

play15:27

user so we know we don't want the user

play15:29

to be able to log or to access the

play15:31

dashboard if they're not already logged

play15:32

in so we can import the or get the G

play15:36

user function from and then we have a

play15:39

function get kind server session my Auto

play15:43

Import for this is a little bit off so

play15:44

this is not going to come from disc it's

play15:46

going to come from the server so there's

play15:48

the import for this function this needs

play15:50

to be inside of an async function so we

play15:53

can await this now these can be async

play15:55

because we're using react server

play15:56

components by default in next js14

play15:59

and so we get this get user function and

play16:01

then we can call this to actually get

play16:02

the user so we can uh say the user is

play16:04

going to come from awaiting the call to

play16:07

the get user function now lastly we know

play16:10

if we don't have a user we we don't want

play16:12

them to access the dashboard so if we

play16:15

don't have a user we can then just run a

play16:17

redirect so we can get a redirect from

play16:20

next navigation I believe and we will uh

play16:23

just redirect them to the homepage we

play16:25

could redirect them to signin or

play16:26

something else in this case we'll just

play16:28

start with the homepage and just kind of

play16:29

kick them

play16:30

out so we can run our application again

play16:33

and just see if this is running now

play16:34

again the next step is to make sure they

play16:35

have a profile which add some additional

play16:37

logic but for now this should just uh

play16:40

navigate the user away if they're not

play16:41

actually logged in so if we go back to

play16:44

uh my events is the SL dasboard page and

play16:47

just to show you this we can go to uh SL

play16:50

dashboard so there's the route for

play16:51

dashboard we're able to get here if we

play16:53

were to log out what we want to check is

play16:56

if we try to manually go to the

play16:58

dashboard route it should just go there

play17:00

and then redirect the user back so we're

play17:02

successfully checking to make sure that

play17:04

a user has to be logged in to actually

play17:05

get to their

play17:06

dashboard now I'm going to go through

play17:08

that signin process again so we can

play17:10

continue to test our signed in user

play17:13

workflow all right so I'm back and

play17:15

signed in now the next thing we want to

play17:17

do is actually check to see if the there

play17:19

is a user profile associated with this

play17:22

user so this is where we're going to

play17:24

start to integrate with Zeta and what

play17:26

we're going to do is we're going to get

play17:27

a reference to The Zeta client so this

play17:30

is going to come from the git Zeta

play17:32

client function so that thing is going

play17:34

to be imported from that Zeta TS file

play17:37

that was just generated for us and

play17:39

that's going to give us access to the

play17:40

Zeta client that we can make queries

play17:42

with and then what we'll do is we will

play17:44

await our client. DB do and then notice

play17:47

in here it gives us intellisense for the

play17:49

tables that we can work with which is

play17:50

pretty neat and then we can call a

play17:52

filter and what do we want to filter by

play17:55

we want to filter by the user ID

play17:57

property where it match matches the user

play17:59

ID of the logged in user so we can get a

play18:02

reference to that ID by destructuring it

play18:06

or just getting it from the user so from

play18:09

the logged in user in kind we want to

play18:11

grab its unique identifier and we're

play18:13

going to use that as our filter to look

play18:15

inside of our Zeta

play18:17

database now from here after the filter

play18:19

we just want to get the first so there

play18:21

should only be one of these we just want

play18:23

to get the first of them and we can uh

play18:26

Alias this in typescript to a user

play18:28

profile

play18:29

record and again this is coming from

play18:31

that Zeta code that was generated for us

play18:33

the user profile record here which has

play18:36

all the properties of the user that we

play18:38

tracked and we can see this inside of

play18:40

here so all of these properties it also

play18:44

has a combination of a Zeta record which

play18:47

Zeta has created at updated at Etc so

play18:50

this is going to give us all the

play18:51

information for that user profile that

play18:53

we would want so in here we'll just uh

play18:56

see uh and call this user profile

play19:00

and then additionally now is where we

play19:02

actually want to check if this user

play19:04

profile doesn't exist we can do the same

play19:06

thing and actually redirect this user

play19:07

away but in this case we specifically

play19:10

want to redirect the user not to the

play19:11

homepage but to the create profile page

play19:14

and you can see that we have a route for

play19:16

this already created which is the create

play19:18

profile page now inside of here there's

play19:21

a lot of work already done inside of the

play19:22

create profile form so I actually skip

play19:24

over this if you want to see this more

play19:25

in depth uh I can do a separate video on

play19:27

this but I don't think it's the most

play19:29

necessary part of this part but

play19:31

basically what we have is a relatively

play19:33

simple form in here that has a spot for

play19:36

name and then for username now the thing

play19:39

the couple things that get a little

play19:40

complicated is being able to do the

play19:42

check with the username so checking the

play19:44

availability and using some debouncing

play19:46

to make sure we're not making too many

play19:47

API requests to the back end to check

play19:50

the availability of that username while

play19:52

it's actually being typed all right so

play19:54

the majority of that code is handled for

play19:57

us now what we want to do is is just

play19:59

look inside of the code that we were

play20:01

working on and just check if we don't

play20:03

have a user profile then we actually

play20:05

want to do our redirect so we can use

play20:08

the same redirect function that we used

play20:09

before and then we'll redirect to the

play20:13

create

play20:15

profile page now we'll actually move

play20:17

this code a little bit here in a second

play20:19

and we'll see why we can take advantages

play20:21

advantage of layouts in nextjs versus

play20:24

just pages but for now let's just see if

play20:26

this works so if we come back to the

play20:28

application and refresh on our dashboard

play20:31

page we should see that we get

play20:33

redirected to the create your profile

play20:35

page and again this has the information

play20:37

already ready to handle the loading

play20:39

State and the checking for the username

play20:42

now the way this is working for the

play20:43

username is it's just doing a query

play20:45

inside of this user profile table with

play20:47

Zeta to see if that username already

play20:49

exists inside of the database now again

play20:52

it also does some debouncing to make

play20:54

sure it's not sending a request every

play20:55

time something changes on the input it

play20:57

has a delay I think of 500 milliseconds

play21:00

we can actually see the delay inside of

play21:02

here if we go and look so we have a

play21:04

debounced username input Handler and it

play21:07

takes a debounce of 500 milliseconds and

play21:09

you can obviously configure this to be

play21:11

whatever you want again let me know if

play21:13

you want a full video on how to do like

play21:14

a live uh feedback username Checker but

play21:18

for now we'll just take advantage of the

play21:20

fact that this is done for us so inside

play21:22

of this uh dashboard page if there is no

play21:25

user profile we want to redirect to the

play21:27

actual create profile profile page now

play21:29

the one additional thing we could do

play21:31

inside of this page is check to see

play21:33

whether or not this profile does Exist

play21:36

by the time we get here so what if

play21:38

someone manually tries to go to the

play21:39

create profile page well we don't want

play21:42

that to happen either so we can actually

play21:44

kind of copy the same exact thing that

play21:46

we just did and in the final code I have

play21:48

this in a separate function but we could

play21:50

copy this exact same code and tweak it

play21:53

just a little bit so we can get all of

play21:55

our Imports we want the Zeta client uh

play21:57

in Zeta and we want the user profile

play21:59

record from Zeta as well and we'll say

play22:02

almost the opposite of these we'll get

play22:03

the user from kind and then we'll just

play22:06

leave this and say redirect away if

play22:08

there is no user from there we'll query

play22:11

for the user profile and then now we'll

play22:13

say if there is a user profile then

play22:16

we'll redirect back to the dashboard

play22:18

page which is SL dashboard so in this

play22:21

case if they already have a profile they

play22:22

don't need to be on the create profile

play22:24

page we'll just redirect them back to

play22:26

the dashboard page and again this only

play22:28

only gets triggered if they try to

play22:30

manually type in SLC create-- profile

play22:34

after being logged after already

play22:36

creating their profile so we're H we

play22:38

have this check on the dashboard page

play22:40

but we also want to apply this to the

play22:42

new event so right now this is a

play22:45

multi-step form and so step one is that

play22:47

new event SL step one so if you wanted

play22:49

to check on each one of the three steps

play22:51

that the user does have a profile we'd

play22:53

have to copy that into three additional

play22:55

pages with the exact same code

play22:57

thankfully though we have access to

play22:58

under dashboard we have a layout and

play23:01

inside of the layout component we can

play23:03

already add our check to make sure there

play23:04

is a user and redirect them if there is

play23:07

not one that means if they try to go to

play23:09

any page inside of Slash dasboard either

play23:12

SL dasboard or SL dashboard slne event

play23:15

SL step-1 Etc it will handle that

play23:18

redirect from here we can just replicate

play23:21

or actually just move this profile code

play23:23

over into the layout and it'll take care

play23:25

of all of those checks for us so again

play23:28

we'll update all of our imports from

play23:31

Zeta here to get our client and our

play23:33

profile record and now at the layout

play23:35

level before we even let them get to any

play23:37

of the children routes we check the user

play23:39

profile to make sure it exists and if

play23:40

not redirect them to the create profile

play23:43

so this means if I try to go to

play23:46

dashboard it should redirect if I try to

play23:49

go to slash dashboard SL new event it

play23:54

will redirect and then if I try to go to

play23:57

any of those in individual step so I

play23:59

could go to SL dasboard Slash new event

play24:02

SL step-1 and that's should redirect and

play24:05

I can do that for step two and three as

play24:07

well so this is how you can protect

play24:09

individual pages from a user that has

play24:12

not completed their onboarding profile

play24:14

now would recommend thinking through

play24:15

what are the things inside of here that

play24:17

are actually required in my case to be

play24:19

able to create an event and to

play24:20

participate in events you have to have a

play24:22

name and a username which makes both of

play24:24

these required before they can go to any

play24:26

of those other pages but you may have

play24:28

additional things like preferences that

play24:30

are not required for the user but would

play24:32

be useful to have so in that case I

play24:34

would end up creating a SL preferences

play24:36

or SL profile page where the user can go

play24:39

and update any of their preferences as

play24:41

they need to so they're not bogged down

play24:43

so they're not slowed down from actually

play24:44

using the application because they

play24:46

haven't filled out information that's

play24:48

not even necessary for them to

play24:49

participate so always think about what

play24:51

pieces of data are actually required for

play24:53

the user and what pieces of data could

play24:54

you let them take care of kind of

play24:56

whenever they're ready or never if they

play24:57

don't need to

play24:59

so there's a lot to think about in a

play25:00

nextjs world on the client on the server

play25:03

using server components server actions

play25:05

Etc hopefully this gives you a better

play25:07

idea of how to handle an onboarding

play25:09

workflow for your users using NEX js14

play25:13

and all the other things that come along

play25:15

with it if you're interested in learning

play25:17

how to build this entire application I'm

play25:18

thinking about turning this into a mini

play25:20

course so if you want to follow along

play25:22

you can follow my newsletter at jamesc

play25:24

quick.com and then scroll down to the

play25:26

footer to subscribe and get updates on

play25:28

weekly basis in the meantime I hope you

play25:30

enjoyed the video and I'll catch you

play25:31

next time

Rate This

5.0 / 5 (0 votes)

Связанные теги
User OnboardingProfile CreationNext.jsAuthenticationWeb DevelopmentUser ExperienceDatabase IntegrationForm HandlingTutorialTech Demo
Вам нужно краткое изложение на английском?