Playing Next Lesson In
seconds

Transcript

  1. So today let's introduce Layouts by moving our authentication shell into a Layout file and using it for both our login and register pages.

  2. So the first thing that we're going to want to do is create a file for our Layout. Now you could create your Layouts inside of your components, but what I like to do in this case

  3. is to create a separate folder altogether called Layouts with my Layouts inside of it directly off of Inertia. So I'm going to create a new file here. We'll call this folder

  4. Layouts and then we'll do AuthLayout.view for the actual Layout file. For right now all that we need is a template. Go ahead and wrap everything

  5. in a div and then we'll have a header with a nav inside of it. And then on this nav we'll do flex items center justify between

  6. with a padding of 6 and a lgpx of 8. Inside of it we'll do an extra div class flex lg flex 1 with

  7. a link component inside of it with an href pointing to the home page. And on this we'll have a class of negative margin 1.5

  8. and a padding of 1.5 as well. Then we'll end that link. Inside of here we'll do a span class sr only and put out a label

  9. for our application of PlotMyCourse. And then we'll grab an svg here in a minute to plop in as our actual icon. So I'll just

  10. put a comment there for right now. And then beside the div inside of our navigation we'll do another div with a class flex flex 1

  11. justify end and a gap of 4. Inside of here we'll put another link component with an href pointing to /register and

  12. a class of text small font semi bold leading 6 and text slate 900. Go ahead and end

  13. that link component. Keeps wanting to do divs for that. I don't know why. And write out register inside of there. We can go ahead and give that link a copy and a paste and switch

  14. the anchor to login instead of register and the text to login instead of register as well. Cool. So we have ourselves a little header here for our

  15. auth layout. Then we need the actual page contents. So let's do another div class and let's apply a padding of 6 there. And then lg will do a padding

  16. of 8. Then we'll do our actual page contents. However from our login page we want to take this div and now move it out to our layout so we can get rid of

  17. it inside of our login page. Just kind of cut it out there. Go ahead and give that a save. Jump back into our auth layout and paste it in. Inside of this div we'll just do a

  18. slot so that any contents that we place inside of our actual page components gets rendered out in this slot right here. Oh! Forgot

  19. about our SVG icon. Let's go ahead and grab that real quick. So let's open up our browser. This is just coming from Lucid. So lucid with an e dot dev. It might

  20. be pronounced Lucide. I'm not quite sure. Go into view all icons and we're just using the routes icon right here. So we can go ahead and give that a click.

  21. Go down to the download SVG. Click on a caret and copy the SVG. Cool. We can close that out for now and hide our browser. Go to where we have our SVG placeholder

  22. and just paste it in. Give it a save so that it formats. Scroll back over to the left. We do want to switch up the class a little bit so we'll do a height of 8

  23. and a width of auto on it and we can give that a save. Alright so your first inclination for using this layout may be to jump into your pages, go into the

  24. template and then try to use your auth layout like so. Wrapping all of your page contents inside of that auth layout and then since that's not inside of our components

  25. directory we would need to import it to register it. So auth layout from we could do tilde slash layouts slash auth

  26. layout dot view. Give that a save and while this will physically work we can jump back into our browser and we'll see everything kind of go back. Oh, one blank less refresh. There we go.

  27. We can see everything kind of go back to how we had it for the page contents and then we also have our header right up here. The downside here is as we click from page to page, now

  28. we don't have it on our register page but assume that we did, it would re-render all of the layouts contents for each link that it goes to. Whereas it would be preferable

  29. if it shared and doesn't actually try to re-render everything as that could result in a flash as it re-renders. So what we want is to

  30. use the layout outside of our page level in between the inertia component and our page component. So we want to elevate this up to our application

  31. level instead of using it inside of our individual pages. So let's go ahead and undo what we did here inside of our logout page. Go ahead and just remove the registration

  32. of our auth layout and remove its usage altogether. And let's jump into our app.ts file. If you remember inside of this file we have a resolve method that's

  33. in charge of resolving out each of our page components as we attempt to render them. Now we can make use of that by intercepting and grabbing a reference to that

  34. component. So for example we could do const page equals resolve component and then down at the bottom of this method return that page. And now we have the actual page

  35. component that we can work with and use to our advantage to add a layout into it. The app component from inertia actually accepts and will read

  36. from a layout property on our page components and then wrap our page in that layout that we provide. For example, if we go ahead

  37. and import our auth layout here. So import auth layout from we'll do ~/layouts/auth-layout.view

  38. there. We have reference to our page so we can do page.default.layout to attach a layout property onto that default export

  39. equals auth layout. Okay so one more thing here. Default does have a red squiggly on it. It is because resolve page component is a promise

  40. so we need to await it and then switch our resolve function to async as well which gets everything being back to happy. And now we need to

  41. inform our server side app about this as well so that we don't get a hydration mismatch. So let's jump into our SSR app and do the exact same thing. So we'll import our

  42. auth layout from ~/layouts/auth-layout and then here too we are using our resolve method to resolve out all of our

  43. pages rather than just one and then finding the applicable page and returning it back. So rather than returning back just like we did within our app we want to save

  44. this into a variable. Now we already have page being provided into this render function up here so what we want to do instead is maybe resolve

  45. page or something of the sort and then just like we did within our app we can do resolve page.default.layout

  46. equals and then apply our auth layout to that property. We'll want to return back that resolve page as well. Alright, we can give that a save.

  47. Now if we jump back into our browser you'll see that everything looks the exact same here for our login page. We can give it a refresh for sanity's sake and it looks the same. Now our register page

  48. never had the layout applied to it but if we click over to it now it does because it's being picked up from our actual application shell now and being applied

  49. by the inertia app component that resides between the inertia component and our page component. So if we inspect, jump into the view dev tools

  50. we can see the root of our application, the inertia component, and then the auth layout now wrapping our actual page component here and this

  51. layout is now being provided by default. We don't need to do anything inside of our actual page to add it in. It will just automatically take hold because

  52. we've added it at the application level.

Creating A Layout

@tomgobich
Published by
@tomgobich
In This Lesson

We'll learn how to create a layout component and apply it to all our pages, the Inertia way.

⏳ Chapters

00:00 - Creating Our Layout
03:06 - Using Our Layout
06:10 - Inspecting Our Layout

Join the Discussion 2 comments

Create a free account to join in on the discussion
  1. 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?

    1
    1. Responding to cubicalprayer712
      @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.

      const page = await resolvePageComponent(
        `../pages/${name}.tsx`,
        import.meta.glob('../pages/**/*.tsx'),
      ) as {
        default: ComponentType & { layout?: (page: ReactElement) => ReactElement }
      }
      
      page.default.layout = page.default.layout
      Copied!
      0