Pages

With Inertia, each page in your application has its own controller and corresponding JavaScript component. This allows you to retrieve just the data necessary for that page, no API required.

Creating pages

Pages are simply JavaScript components. There is nothing particularly special about them. Pages receive data from the controllers as props. Here's an example of a simple page component.

<template>
  <layout title="Welcome">
    <h1>Welcome</h1>
    <p>Hello {{ user.name }}, welcome to your first Inertia app!</p>
  </layout>
</template>

<script>
  import Layout from '@/Shared/Layout'

  export default {
    components: {
      Layout,
    },
    props: {
      user: Object,
    },
  }
</script>

Creating layouts

While not required, for most projects it makes sense to create a site layout that your pages can extend. Notice in our page example above that we're wrapping the page content within a <layout> component. Here's an example of such a component. There is nothing Inertia specific here. This is just a standard JavaScript component.

<template>
  <main>
    <header>
      <inertia-link href="/">Home</inertia-link>
      <inertia-link href="/about">About</inertia-link>
      <inertia-link href="/contact">Contact</inertia-link>
    </header>
    <article>
      <slot />
    </article>
  </main>
</template>

<script>
  export default {
    props: {
      title: String,
    },
    watch: {
      title: {
        immediate: true,
        handler(title) {
          document.title = title
        },
      },
    },
  }
</script>

Persistent layouts

While it's simple to implement layouts as children of the page components, it does force the layout instance to be destroyed and recreated between visits. This means you cannot have persistent layout state when navigating between pages.

For example, maybe you have an audio player on a podcast website that you want to continue playing as users navigate the site. Or, maybe you simply want to maintain the scroll position in your navigation between page visits. In these situations, using the persistent layouts feature in Inertia is a better choice.

<template>
  <div>
    <h1>Welcome</h1>
    <p>Hello {{ user.name }}, welcome to your first Inertia app!</p>
  </div>
</template>

<script>
  import Layout from '@/Shared/Layout'

  export default {
    layout: Layout,
    props: {
      user: Object,
    },
  }
</script>

You can optionally make layout a render function, allowing you to create more complex layout arrangements. For example, you can use this to create a secondary nested layout within a subsection of your app.

<template>
  <div>
    <h1>Welcome</h1>
    <p>Hello {{ user.name }}, welcome to your first Inertia app!</p>
  </div>
</template>

<script>
  import SiteLayout from './SiteLayout'
  import NestedLayout from './NestedLayout'

  export default {
    layout: (h, page) => {
      return h(SiteLayout, [
        h(NestedLayout, [page]),
      ])
    },
    props: {
      user: Object,
    },
  }
</script>

Scroll regions

When navigating between pages, Inertia will automatically reset the scroll position to the top of the body (unless disabled via the preserve-scroll functionality). Depending on your app, you may have nested scroll containers within your layout, and these will not be reset by default. You can tell Inertia to also reset these areas by adding a scroll-region attribute.

<div class="overflow-y-auto" scroll-region>
  <!-- Your page content -->
</div>