Client-side setup
TIP
If you used the template based setup, you can skip client-side setup. It is already configured as part of the template based setup.
Once you have server-side configured, you then need to setup your client-side framework. Inertia currently provides support for React, Vue, and Svelte.
Install dependencies
First, install the Inertia client-side adapter corresponding to your framework of choice.
npm install @inertiajs/vue3 vue @vitejs/plugin-vue
npm install @inertiajs/react react react-dom @vitejs/plugin-react
npm install @inertiajs/svelte svelte @sveltejs/vite-plugin-svelte
Configure Vite
Create a vite.config.js
file in your root directory and configure it for use with your frontend of choice and django-vite
.
// vite.config.js
import { join, resolve } from "node:path";
import vue from "@vitejs/plugin-vue";
import { defineConfig, loadEnv } from "vite";
export default defineConfig((mode) => {
const env = loadEnv(mode, process.cwd(), "");
const INPUT_DIR = "./frontend";
const OUTPUT_DIR = "./frontend/dist";
return {
plugins: [vue()],
resolve: {
alias: {
"@": resolve(INPUT_DIR),
vue: "vue/dist/vue.esm-bundler.js",
},
},
root: resolve(INPUT_DIR),
base: "/static/",
server: {
host: "0.0.0.0",
port: env.DJANGO_VITE_DEV_SERVER_PORT || 5173,
watch: {
usePolling: true,
},
},
build: {
manifest: "manifest.json",
emptyOutDir: true,
outDir: resolve(OUTPUT_DIR),
rollupOptions: {
input: {
main: join(INPUT_DIR, "/js/main.js"),
css: join(INPUT_DIR, "/css/main.css"),
},
},
},
};
});
// vite.config.js
import { join, resolve } from "node:path";
import react from '@vitejs/plugin-react';
import { defineConfig, loadEnv } from "vite";
export default defineConfig((mode) => {
const env = loadEnv(mode, process.cwd(), "");
const INPUT_DIR = "./frontend";
const OUTPUT_DIR = "./frontend/dist";
return {
plugins: [react()],
resolve: {
alias: {
"@": resolve(INPUT_DIR),
},
},
root: resolve(INPUT_DIR),
base: "/static/",
server: {
host: "0.0.0.0",
port: env.DJANGO_VITE_DEV_SERVER_PORT || 5173,
watch: {
usePolling: true,
},
},
build: {
manifest: "manifest.json",
emptyOutDir: true,
outDir: resolve(OUTPUT_DIR),
rollupOptions: {
input: {
main: join(INPUT_DIR, "/js/main.js"),
css: join(INPUT_DIR, "/css/main.css"),
},
},
},
};
});
// vite.config.js
import { join, resolve } from "node:path";
import { svelte } from '@sveltejs/vite-plugin-svelte';
import { defineConfig, loadEnv } from "vite";
export default defineConfig((mode) => {
const env = loadEnv(mode, process.cwd(), "");
const INPUT_DIR = "./frontend";
const OUTPUT_DIR = "./frontend/dist";
return {
plugins: [svelte()],
resolve: {
alias: {
"@": resolve(INPUT_DIR),
},
},
root: resolve(INPUT_DIR),
base: "/static/",
server: {
host: "0.0.0.0",
port: env.DJANGO_VITE_DEV_SERVER_PORT || 5173,
watch: {
usePolling: true,
},
},
build: {
manifest: "manifest.json",
emptyOutDir: true,
outDir: resolve(OUTPUT_DIR),
rollupOptions: {
input: {
main: join(INPUT_DIR, "/js/main.js"),
css: join(INPUT_DIR, "/css/main.css"),
},
},
},
};
});
Initialize the Inertia app
Create a frontend
directory in your root directory and add a js
directory inside it. Inside the js
directory, create a main.js
file.
Next, update your main JavaScript file (main.js
) to boot your Inertia app. To accomplish this, we'll initialize the client-side framework with the base Inertia component.
We will also configure CSRF to work properly with Django.
// frontend/js/main.js
import { createApp, h } from "vue";
import { createInertiaApp } from "@inertiajs/vue3";
import axios from "axios";
document.addEventListener("DOMContentLoaded", () => {
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
createInertiaApp({
resolve: (name) => {
const pages = import.meta.glob("../pages/**/*.vue", { eager: true });
return pages[`../pages/${name}.vue`];
},
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.mount(el);
},
});
});
// frontend/js/main.js
import { createInertiaApp } from "@inertiajs/react";
import { createElement } from "react";
import { createRoot } from "react-dom/client";
import axios from "axios";
document.addEventListener("DOMContentLoaded", () => {
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
createInertiaApp({
resolve: (name) => {
const pages = import.meta.glob("../pages/**/*.jsx", { eager: true });
return pages[`../pages/${name}.jsx`];
},
setup({ el, App, props }) {
const root = createRoot(el);
root.render(createElement(App, props));
},
});
});
// frontend/js/main.js
import { createInertiaApp } from "@inertiajs/svelte";
import axios from "axios";
document.addEventListener("DOMContentLoaded", () => {
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
createInertiaApp({
resolve: (name) => {
const pages = import.meta.glob("../pages/**/*.svelte", { eager: true });
return pages[`../pages/${name}.svelte`];
},
setup({ el, App, props }) {
new App({ target: el, props });
},
});
});
// frontend/js/main.js
import { createInertiaApp } from "@inertiajs/svelte";
import { mount } from "svelte";
createInertiaApp({
resolve: (name) => {
const pages = import.meta.glob("./Pages/**/*.svelte", { eager: true });
return pages[`./Pages/${name}.svelte`];
},
setup({ el, App, props }) {
mount(App, { target: el, props });
},
});
The setup
callback receives everything necessary to initialize the client-side framework, including the root Inertia App
component.
Resolving components
The resolve
callback tells Inertia how to load a page component. It receives a page name (string), and returns a page component module. How you implement this callback depends on which bundler (Vite or Webpack) you're using.
// frontend/js/main.js
createInertiaApp({
resolve: (name) => {
const pages = import.meta.glob("../pages/**/*.vue", { eager: true });
return pages[`../pages/${name}.vue`];
},
// ...
});
// frontend/js/main.js
createInertiaApp({
resolve: (name) => {
const pages = import.meta.glob("../pages/**/*.jsx", { eager: true });
return pages[`../pages/${name}.jsx`];
},
//...
});
// frontend/js/main.js
createInertiaApp({
resolve: (name) => {
const pages = import.meta.glob("../pages/**/*.svelte", { eager: true });
return pages[`../pages/${name}.svelte`];
},
//...
});
By default we recommend eager loading your components, which will result in a single JavaScript bundle. However, if you'd like to lazy-load your components, see our code splitting documentation.
Defining a root element
By default, Inertia assumes that your application's root template has a root element with an id
of app
. This is already configured if you use the {% block inertia %} {% endblock %}
template tag from inertia-django
in your base html template.
If your application's root element has a different id
, you can provide it using the id
property.
createInertiaApp({
id: "my-app",
// ...
});