Great, so now that we have authentication set up, we are ready to start exploring how organizations work. And thankfully, Clerk does all of that for us. So let's go ahead, head back inside of Clerk. So right now you should have this kind of screen. You can see I have my user here and let's go ahead and click on organizations right here let me just zoom in so you can see so right here on the organizations and inside you can see that organizations have not been enabled for this application so go ahead and click enable organizations and that's going to redirect you to organization settings here and just enable them like this.
Great perfect so make sure organizations are enabled and there we go now we have organizations here. Great! So you can now close Clerk, no need to do anything further. And what I want to create now is a protected route which we are going to use to select an Organization or to create a new one. So let's go inside of the app folder Let's go inside of the platform inside of clerk right here and create a new folder called Select dash org like that and inside create another folder with double square brackets and the catch all route inside select-org again.
And then add a page.tsx. So make sure it's inside of this clerk folder. So this select-org route is also going to share the same layout where we centered our children so we don't have to worry about that. Perfect and inside of here all I want to do is import organization list from clerk next js and export default function create organization page like that and just return organization list. Perfect and now let's go ahead and log in.
I'm just gonna go ahead and do that and now that I'm logged in I'm gonna go and manually go to slash select dash org like this. And there we go. As you can see from here, I can either select my personal account or I can click create an organization. From here I can upload a specific image but I don't have to and I can go ahead and give this you know a name for example Foo Incorporated and I can click create organization And from here I can add email addresses to invite some other members and I can immediately assign the roles to be members or admins. For now I'm going to skip that.
Perfect! And there we go. Now we have my organization right here. And I can click here and now I have selected my organization but nothing seems to be happening here and that's because we need to add some additional options to this component right here. So the first option is that we remove this personal account.
So this is going to be primarily a business-to-business software so let's go ahead and write hide personal inside of this component and now when you refresh a select org as you can see we no longer have that personal option. Great and now what I want to do is add after select organization URL let's go ahead and redirect to let me just extract this sorry expand this so we want to redirect to organization slash ID like this so this is this is gonna be recognized inside of this prop that this is a slug. This is a dynamic part of a URL. And below that we're going to copy and paste this and change this to After create organization URL. So this one is after select and this one is after create.
Perfect. So, let's go ahead and try that out. I'm just going to hit refresh here. Make sure you do that as well. Let's click here and we should be redirected to a 404 page.
But check a look at the URL. It says organization slash and the organization id in the url perfect so that is exactly what we needed and now we're just going to go ahead and quickly create those pages So we have to go back inside of our platform organizational route so let me close everything here go inside of the app folder platform right here and let's go ahead and create another organizational folder besides clerk which is going to be our dashboard like this and inside go ahead and create a new folder called organization like that and then another folder which is going to be organization ID great and then we can create a page .dsx inside and let's write const organization ID page return a div saying organization page like this and export the default organization ID page perfect and as you can see I no longer have that error now because my URL matches slash organization and then the organization ID. So if you're having any problems, go ahead and confirm that you have a folder called organization and the folder called organization ID. It doesn't matter if you put it inside of this organizational route, because remember this is omitted from the URL.
So this dashboard is not inside of the URL. Platform is not inside of the URL as well. Right? So none of this make the URL but only here we actually start with the URL because this has no parentheses around it. And this, if you remember from the first part of this tutorial, is a dynamic part of the URL.
And if it's still not working and this is correct, then go ahead again into the platform, but this time into Clerk, and then go inside of select org right here in this page and confirm that you didn't misspell something here perhaps there's an S here instead of Z or something like that. Great! And now you're actually gonna see how useful these organizational routes are once again because as you can see here in my clerk folder I share a specific layout where I just Center all of these items, but here in dashboard, that's not happening. So that's why we created a specific Organizational route, but at this time just for the dashboard. So for now what I want to do is I actually want to show you how to fetch some organization information so you can use the auth which we already played around with from clerk-next.js and from here besides the user ID you can also extract the org ID like this.
So let's go ahead and write organization and org ID like this. Perfect! As you can see now we have the organization and the org ID is right here. You can see that it matches what is in the URL. Perfect!
And now let's go ahead and let me show you another component which we have. So I'm gonna remove this for now and Let's add the organization switcher component. Import that from clerk next JS and let me just close it. So it's a self-closing tag and you can see how that looks. So similar to like that user button component.
As you can see right here, I can switch, I can manage my organization from here. I can check out my users, a bunch of stuff like that. Perfect! And in here I can still switch to personal account but also from here you can add that prop, hide personal and after you refresh it's not gonna be here and from here you can also trigger a creation of organization if it is faster for your users so very very convenient component perfect So what I want to do now is I actually just want to bring this back to say organization page We don't need this hooks We don't need this like that And just save it like this because now we're gonna create a specific layout only for this dashboard component, sorry for this dashboard organizational route and we're going to start and create a little navbar and add all of those components there. So let's go ahead inside of the dashboard organizational folder and create a new file layout.tsx so let me just collapse this organizational folder just to show you that this layout file is inside of dashboard not inside of organization That's important because we're gonna have some more routes here which are gonna be inside of the dashboard Organizational folder so go inside of this layout and add cons Dashboard layout and you already know that we can immediately extract children from this Sorry, let's give them a type So children are a type of react.reactNode.
And let's go ahead and return a div and let's render the children. And we also have the export default dashboard layout. And let's just not misspell that. All right, and there we go. No, no more errors.
Perfect. And now what I want to do is I want to give this div a class name of HeightFull and then I want to render a NavBar component from here but once I save this I'm going to get an error because the NavBar component does not exist So inside of this dashboard right here go ahead and create a new folder underscore components and inside of here create a new file navbar.tsx like that perfect let's export const navbar and let's return a div saying navbar like this and then we can immediately go back inside of our layout and we can fix this undefined error So make sure you don't import the navbar from the marketing page, right? That's the different one. We're going to import this closest to us. ./.components.navbar And once you save, we have a nice little text navbar here.
Perfect. All right. And now let's go ahead and open a new div here with a class name of flex items dash center and gap X4. And just above this div, I'm gonna add a little comment, mobile sidebar. So this is just for me.
You didn't have to write this but just for me to remember that we need to handle responsivity at some point but we're gonna do that later. First we have to implement the desktop sidebar right? And inside of here I'm gonna Go ahead and open a div with a class name hidden and the flex so this is only gonna be visible on desktop not on mobile and that's gonna be our logo component which we created and stored in s slash components logo like this. Perfect. So now if I expand from here there we go you can see our nice little logo here.
Perfect. And let's also go ahead and give this div which holds our navbar a px4. And let's also maybe change this from div to nav right to be more semantically correct there we go, alright and now outside of this div right here which holds our logo just go ahead and import a button from components UI button as I did right here and let's just go ahead and write create like this. Perfect and Let's give this one a size of small and let's give it a class name of rounded small hidden MD block H auto py 1.5 and px 2 So let me just go ahead and add a little space here so you can see exactly Py is 1.5 and Px is 2. Like this.
And there we go you can see our little button here now. Perfect. And I just want to go ahead and add another button here. Which is going to have a different size, sorry a different look so class name is gonna be a rounded small block and MD hidden and inside of here render a plus from Lucid React like that. So this is only going to be visible on mobile devices and give this plus a class name of H-4NW-4 like that and since this is from npm I'm going to move that import to the top.
Perfect. So this is how it looks on mobile. We just have a little plus button, but on desktop, we have a big create button. And Now that I'm looking at it, it kind of feels like we could have done this in a better way. Instead of making this hidden and empty block on the button, we can actually do it.
Oh yeah, but then we have to wrap this into a span. I don't know. Let's leave it like this for now. I think it's fine. Yeah, perhaps we could have improved Reusing the same component, but you know, I don't think it's a big deal.
You can play around with it if you want Great. Alright, so now that we have that what I want to add outside of this div so just here in this empty space before we close the navbar is a new div with a class name of ML-AutoFlexItems-Center and GapX2 and inside of here we're going to render our organizational switcher sorry, organization switcher from clerk next.js so make sure you import organization switcher from clerk next.js like that and let's go ahead and give it some props. So first hide personal, we already know that. After create organization URL, we're gonna go to slash organization ID. After leave organization URL, we're gonna go to slash select dash org like that.
After, what's left after, select organization URL that's also gonna go to slash organization slash ID like that and now I'm just gonna modify the appearance a bit so I'm gonna write appearance elements I'm gonna go inside of the root box and I'm gonna add display to be flex. So display is going to be flex, justify content is going to be center and align items is going to be center as well. Perfect. Great, so we just improved this little image here. Usually without this styling it just looks a tiny bit off in comparison to all the other elements which we are going to have.
Great! And just below this organization switcher, we're also going to add the user button from clerk slash nextjs. So import this user button from clerk slash next.js right here and go ahead and give it an after sign out URL to be a slash and appearance is going to be elements avatar box and inside of here give it a height of 30 and a width of 30 as well. Perfect! So now we have all of those elements inside of our navbar here.
Perfect! But we're not exactly finished now because I can still go to localhost 3000 and as you can see I can visit my landing page but I don't want that to happen right. In fact I always want to be on one specific organization right even if I haven't selected any organization I want in that case I want to get redirected to that slash select org or route which we created right So let's go ahead and modify our middleware to do exactly that. So we're gonna improve our middleware a bit. Usually we pretty much never attach the middleware in my tutorials but you know this is a really cool feature that the clerk has this organization so we get to play around with it a bit so let's go ahead and write after auth this is a function which will give us an auth and a request and let's go ahead and open it and first thing that I want to check if we are authenticated and we're going to do that using auth.userid so if we have the user id it means we are authenticated and then we're going to check if we are on the public route so if Auth is public route so this means if we are logged in and if we are visiting the landing page in that case I want to redirect to either my organization ID or to select org So let's write the initial path which we want to redirect the user is going to be select org.
Right if they are logged in and they attempt to visit the landing page we're just going to push them back to select an organization. But if we have the user organization id In that case the path is going to become, make sure you write this inside of backdex slash organization slash individualauth dot organization ID. Right? So we are going to move them to there. And now we just have to create a function to do that.
So const orgSelection is going to be new URL. We get the current path which we have and we combine it with request.url. And then we do return nextResponse which we can import from next slash server so just make sure you add this little import so return next response dot redirect org selection like that perfect And now outside of this big if clause which we've just written we have to handle some other regular cases which we might have. So if we are not authenticated and if we are not on a public route we have to explicitly tell what to do and that's going to be very simple. We're just going to return redirect to sign in from clerk slash next JS.
So just make sure you import redirect to sign in from clerk next JS. And we're simply going to pass in the URL from where they came from. So once they log in, like obviously this user which is not logged in, tried to access a private route. Perhaps it was bookmarked or perhaps they had a link, right? So if they attempt to do that and we tell them that they need to log in first, it will be nice of us to give them a return back URL.
So once they log in, we're just gonna give them the current URL they just tried to access. And last one we have to check is if we are logged in, so if auth has the user ID and if we don't have auth.org.id and if request.nexturl.pathname is not slash select dash org let me see if I can expand my screen just a bit more so you can see it in one line basically let me show you so this is the if clause if we have the user ID and we don't have a specified organization, meaning we never selected any organization. And if we are not on slash select organization, basically, if the user is trying to do anything, even if they're logged in, but they don't have an organization, we have to force them to create an organization or select one first except if they are on that page where we do the organization selection so just make sure you don't have any typos here otherwise you might create some infinite loops here. So const orgSelection is new URL slash select dash org and request dot URL and return next response dot redirect org selection like that and that is it.
That is our middleware. So make sure you save this. If you're having any issues, you can always copy it directly from my GitHub. And now let's try this out. So I'm gonna go ahead and attempt to go to localhost 3000.
And as you can see, I'm immediately redirected back to my organization. Perfect. But what about if I create a completely new account? What happens then? So let me just go ahead and log out.
All right so I just logged out and let's just confirm that I cannot go anywhere. So I'm gonna try the organization. There we go. That is not working. And now let me just go back to localhost 3000 so I'm allowed to go on the landing page and now I'm gonna log in but with a completely different account that has never selected any organization.
Let's see what happens then. There we go as you can see I'm redirected directly to slash select dash org right and let's try and clean let's attempt to go to landing page now. As you can see, we cannot. So if the user is logged in, but we have not created an organization, we need to make the user create their own, right? So create the organization, skip, and there we go.
We are back inside of here. Perfect, amazing, amazing job. Just one tiny bit thing that I want to create is I want to create a special variant for our button here so it's kind of a bluish color rather than this one. For that we have to visit our button component in chat.cn sorry in the UI folder so components UI this is the chat.cn button right so make sure you are here And then inside of this variants we have default, destructive, outline, secondary, ghost and link and we're going to add our own. So we're going to add primary and that's going to be bg-sky-700 like this.
Text-primary-foreground hover bg-sky-700-90 like this. So we just added this one line and then we can go inside of our app folder inside of the platform dashboard components navbar right here and we can give both of these buttons a new variant which is going to be as you can see now we even have the autocomplete for it primary and if I save there we go you can see how now it has a nice bluish color and currently it doesn't do anything but later it's gonna open a little form in a type of popover. Perfect! So you have started working on organizations, your middleware is working and you have completely completed the auth and now it's time for us to start working on the sidebar here and actually rendering some information about the user's current organization. Great, great job.