Frontend & Theming
Beautiful, accessible, and customizable UI.
Inertia Start's frontend is built with Vue.js 3, TypeScript 6, and Tailwind CSS 4, leveraging the popular shadcn-vue library. It relies on Laravel Vite for asset bundling.
Browse the component showcasePreview the buttons, forms, overlays and more that ship with Inertia Start.
Components
We use shadcn-vue, which provides accessible, unstyled components that you can copy and paste into your apps. These components are fully typed and customizable.
Official shadcn-vue components
Shadcn-vue components are located in resources/js/components/ui.
You can find other components here.
Example adding the Switch component:
npx shadcn-vue@latest add switchThe command will publish the Switch component to resources/js/components/ui/Switch.vue.
Then, use it in your pages:
<script setup lang="ts">
import { Switch } from '@/components/ui/switch'
</script>
<template>
<div>
<Switch />
</div>
</template>Custom components
Inertia Start includes its own customized versions of several shadcn-vue components, extending them with new features and optimizing them for Inertia Start’s specific needs.
In addition to the shadcn-vue components, Inertia Start provides a variety of custom components, all located in resources/js/components.
Extend with third-party components
Here is a list of well-known component libraries, but there are many others:
Theming
Included themes
Theming is built on CSS variables, making it incredibly easy to customize. Inertia Start provides 27 primary colors and 26 secondary colors, based on the curated Tailwind palette.
Learn how to use built-in themes in the Colors section of the configuration docs.
Customizing
To change the look and feel, you can tweak the CSS variables in resources/css/app.css or use a tool like tweakcn to generate your theme.
Light & Dark Mode
Full support for Light and Dark modes is included. By default, the two modes are enabled.
You can configure which mode are enabled using the I_S_THEME environment variable. Possible values are:
null: The two mode will be enabled. By default, the mode will automatically match the preferences of the user's device, unless the user selects a specific theme via the theme selector component.lightordark: only the Light or Dark mode will be enabled and forced, no matter the preferences of the user's device. The theme switcher will not be displayed.
Example, enabling only the Dark mode:
I_S_THEME=darkApp layouts
Inertia Start ships with two authenticated application shells:
sidebar: the default navigation layout with the main navigation in a collapsible sidebar.header: a top navigation layout that renders the navigation in the page header.
Switch between them with the I_S_APP_LAYOUT environment variable:
I_S_APP_LAYOUT=headerresources/js/layouts/AppLayout.vue acts as the wrapper and chooses between resources/js/layouts/app/AppSidebarLayout.vue and resources/js/layouts/app/AppHeaderLayout.vue based on the shared appLayout prop.
Because the chosen layout is shared through Inertia, you can also branch on it from your own Vue components:
<script setup lang="ts">
import { computed } from 'vue'
import { usePage } from '@inertiajs/vue3'
const page = usePage()
const isHeaderLayout = computed(() => page.props.appLayout === 'header')
</script>Breadcrumbs
The app, admin, and account layouts display a breadcrumb trail. Set it from a page's <script setup> with the helpers from resources/js/utils/breadcrumbs.ts:
setBreadcrumbItems()replaces the whole trail.addBreadcrumbItems()appends items to the trail provided by the layout.AccountLayoutprovides My account followed by the account navigation, whileAppLayoutandAdminLayoutprovide an empty trail.
<script setup lang="ts">
import { setBreadcrumbItems } from '@/utils/breadcrumbs'
setBreadcrumbItems([
{ title: 'Dashboard', href: route('dashboard') },
{ title: 'Projects' },
])
</script>Each item accepts a title and an optional href and icon. The last item is displayed as the current page. An item can also be an array of navigation items, displayed as a select menu to switch between sibling pages (this is how AccountLayout renders the account navigation).
When the trail depends on reactive data, such as props, pass a function instead of an array. The trail is updated whenever that data changes:
<script setup lang="ts">
import { addBreadcrumbItems } from '@/utils/breadcrumbs'
const props = defineProps<{ project: { name: string } }>()
addBreadcrumbItems(() => [{ title: props.project.name }])
</script>The helpers set the breadcrumbs layout prop. If you build your own layout, type its breadcrumbs prop as BreadcrumbItemsProp and resolve it with resolveBreadcrumbItems(defaultBreadcrumbs, props.breadcrumbs): it accepts either an array that replaces the default trail, or a function that receives the default trail and returns a new one.
Fonts
Fonts are managed with Fontsource. By default, the project uses Inter for the main font and Space Grotesk for headings.
To change or add fonts, go to the fonts configuration guide.
Icons
Inertia Start uses icons from Lucide.
Animations
Inertia Start uses Motion for some of its animations (for example, the price animation in the pricing cards implemented by the AnimatedPrice.vue component).
You may also use @vueuse/motion and its ready-to-use presets.