00:05
So today let's introduce Layouts by moving our authentication shell
00:09
into a Layout file and using it for both our login and register pages.
00:13
So the first thing that we're going to want to do is create a file for our Layout.
00:16
Now you could create your Layouts inside of your components, but what I like to do in this case
00:20
is to create a separate folder altogether called Layouts with my Layouts inside of it
00:24
directly off of Inertia. So I'm going to create a new file here. We'll call this folder
00:28
Layouts and then we'll do AuthLayout.view for the actual Layout file.
00:32
For right now all that we need is a template. Go ahead and wrap everything
00:36
in a div and then we'll have a header with a nav inside of it. And then on this
00:40
nav we'll do flex items center justify between
00:44
with a padding of 6 and a lgpx of 8. Inside of it we'll do an
00:48
extra div class flex lg flex 1 with
00:52
a link component inside of it with an href pointing to the home page.
00:56
And on this we'll have a class of negative margin 1.5
01:00
and a padding of 1.5 as well. Then we'll end that link.
01:04
Inside of here we'll do a span class sr only and put out a label
01:08
for our application of PlotMyCourse. And then we'll grab an svg
01:12
here in a minute to plop in as our actual icon. So I'll just
01:16
put a comment there for right now. And then beside the div inside of our navigation
01:20
we'll do another div with a class flex flex 1
01:24
justify end and a gap of 4. Inside of here we'll put
01:28
another link component with an href pointing to /register and
01:32
a class of text small font semi bold leading
01:36
6 and text slate 900. Go ahead and end
01:40
that link component. Keeps wanting to do divs for that. I don't know why. And write out
01:44
register inside of there. We can go ahead and give that link a copy and a paste and switch
01:48
the anchor to login instead of register and the text to login
01:52
instead of register as well. Cool. So we have ourselves a little header here for our
01:56
auth layout. Then we need the actual page contents. So let's do another div
02:00
class and let's apply a padding of 6 there. And then lg will do a padding
02:04
of 8. Then we'll do our actual page contents. However from our login
02:08
page we want to take this div and now move it out to our layout so we can get rid of
02:12
it inside of our login page. Just kind of cut it out there. Go ahead and give that a save.
02:16
Jump back into our auth layout and paste it in. Inside of this div we'll just do a
02:20
slot so that any contents that we place inside of our actual page
02:24
components gets rendered out in this slot right here. Oh! Forgot
02:28
about our SVG icon. Let's go ahead and grab that real quick. So let's open up our browser. This is
02:32
just coming from Lucid. So lucid with an e dot dev. It might
02:36
be pronounced Lucide. I'm not quite sure. Go into view all icons and
02:40
we're just using the routes icon right here. So we can go ahead and give that a click.
02:44
Go down to the download SVG. Click on a caret and copy the SVG. Cool.
02:48
We can close that out for now and hide our browser. Go to where we have our SVG placeholder
02:52
and just paste it in. Give it a save so that it formats. Scroll back over to the left.
02:56
We do want to switch up the class a little bit so we'll do a height of 8
03:00
and a width of auto on it and we can give that a save. Alright so your first
03:04
inclination for using this layout may be to jump into your pages, go into the
03:08
template and then try to use your auth layout like so. Wrapping
03:12
all of your page contents inside of that auth layout and then since that's not inside of our components
03:16
directory we would need to import it to register it. So auth layout
03:20
from we could do tilde slash layouts slash auth
03:24
layout dot view. Give that a save and while this will physically work we can jump
03:28
back into our browser and we'll see everything kind of go back. Oh, one blank less refresh. There we go.
03:32
We can see everything kind of go back to how we had it for the page contents and then we also have
03:36
our header right up here. The downside here is as we click from page to page, now
03:40
we don't have it on our register page but assume that we did, it would re-render all of the layouts
03:44
contents for each link that it goes to. Whereas it would be preferable
03:48
if it shared and doesn't actually try to re-render everything as that could
03:52
result in a flash as it re-renders. So what we want is to
03:56
use the layout outside of our page level in between the inertia component
04:00
and our page component. So we want to elevate this up to our application
04:04
level instead of using it inside of our individual pages. So
04:08
let's go ahead and undo what we did here inside of our logout page. Go ahead and just remove the registration
04:12
of our auth layout and remove its usage altogether. And let's jump into our
04:16
app.ts file. If you remember inside of this file we have a resolve method that's
04:20
in charge of resolving out each of our page components as we attempt to render them.
04:24
Now we can make use of that by intercepting and grabbing a reference to that
04:28
component. So for example we could do const page equals resolve component
04:32
and then down at the bottom of this method return that page. And now we have the actual page
04:36
component that we can work with and use to our advantage to add a layout into it.
04:40
The app component from inertia actually accepts and will read
04:44
from a layout property on our page components and then
04:48
wrap our page in that layout that we provide. For example, if we go ahead
04:52
and import our auth layout here. So import auth layout from
04:56
we'll do ~/layouts/auth-layout.view
05:00
there. We have reference to our page so we can do page.default.layout
05:04
to attach a layout property onto that default export
05:08
equals auth layout. Okay so one more thing here. Default
05:12
does have a red squiggly on it. It is because resolve page component is a promise
05:16
so we need to await it and then switch our resolve function to
05:20
async as well which gets everything being back to happy. And now we need to
05:24
inform our server side app about this as well so that we don't get a hydration mismatch.
05:28
So let's jump into our SSR app and do the exact same thing. So we'll import our
05:32
auth layout from ~/layouts/auth-layout
05:36
and then here too we are using our resolve method to resolve out all of our
05:40
pages rather than just one and then finding the applicable page and returning
05:44
it back. So rather than returning back just like we did within our app we want to save
05:48
this into a variable. Now we already have page being provided into this render
05:52
function up here so what we want to do instead is maybe resolve
05:56
page or something of the sort and then just like we did within our app
06:00
we can do resolve page.default.layout
06:04
equals and then apply our auth layout to that property.
06:08
We'll want to return back that resolve page as well. Alright, we can give that a save.
06:12
Now if we jump back into our browser you'll see that everything looks the exact same here for our login
06:16
page. We can give it a refresh for sanity's sake and it looks the same. Now our register page
06:20
never had the layout applied to it but if we click over to it now it does because
06:24
it's being picked up from our actual application shell now and being applied
06:28
by the inertia app component that resides between the inertia component
06:32
and our page component. So if we inspect, jump into the view dev tools
06:36
we can see the root of our application, the inertia component, and then
06:40
the auth layout now wrapping our actual page component here and this
06:44
layout is now being provided by default. We don't need to do anything inside of our
06:48
actual page to add it in. It will just automatically take hold because
06:52
we've added it at the application level.
Join The Discussion! (2 Comments)
Please sign in or sign up for free to join in on the dicussion.
cubicalprayer712
If we do something like this in react
```
resolve: async (name) => {
const page = await resolvePageComponent(`../pages/${name}.tsx`, import.meta.glob('../pages/**/*.tsx'))
page.default.layout = page.default.layout || (page => <MainLayout>{page}</MainLayout>)
return page
}
```
We get typescript errors that
page is of type unknown
, what would be the proper typing for page?Please sign in or sign up for free to reply
tomgobich
Hi cubicalprayer712!
Vladimir kindly left steps on getting this setup in React in the next lesson's comments if you'd like more details, but something like the below should satisfy the needed typing.
Please sign in or sign up for free to reply