diff --git a/README.md b/README.md
index 3a7e1cd..60a74f0 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,15 @@
# InertiaRailsContrib
-A collection of extensions, developer tools, and the [community documentation](https://inertia-rails.netlify.app) for [Inertia's Rails adapter](https://github.com/inertiajs/inertia-rails).
+A collection of extensions and developer tools for [Inertia's Rails adapter](https://github.com/inertiajs/inertia-rails).
+> Community documentation has been moved to the [Inertia Rails repository](https://github.com/inertiajs/inertia-rails).
+>
+> Please visit the official Inertia Rails documentation at https://inertia-rails.dev.
+
## Installation
Install the gem and add to the application's Gemfile by executing:
diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts
deleted file mode 100644
index 170800b..0000000
--- a/docs/.vitepress/config.mts
+++ /dev/null
@@ -1,162 +0,0 @@
-import { defineConfig } from "vitepress";
-import { tabsMarkdownPlugin } from "vitepress-plugin-tabs";
-
-const title = "Inertia Rails";
-const description = "Community documentation for Inertia.js Rails adapter";
-const site = "https://inertia-rails.netlify.app";
-const image = `${site}/og_image.jpg`;
-
-// https://vitepress.dev/reference/site-config
-export default defineConfig({
- title,
- description,
-
- markdown: {
- config(md) {
- md.use(tabsMarkdownPlugin);
- },
- },
-
- head: [
- ["link", { rel: "icon", href: "/favicon.ico", sizes: "32x32" }],
- ["link", { rel: "icon", href: "/icon.svg", type: "image/svg+xml" }],
-
- ["meta", { name: "twitter:card", content: "summary_large_image" }],
- ["meta", { name: "twitter:site", content: site }],
- ["meta", { name: "twitter:description", value: description }],
- ["meta", { name: "twitter:image", content: image }],
-
- ["meta", { property: "og:type", content: "website" }],
- ["meta", { property: "og:locale", content: "en_US" }],
- ["meta", { property: "og:site", content: site }],
- ["meta", { property: "og:site_name", content: title }],
- ["meta", { property: "og:image", content: image }],
- ["meta", { property: "og:description", content: description }],
- ],
-
- themeConfig: {
- // https://vitepress.dev/reference/default-theme-config
- nav: [
- { text: "Home", link: "/" },
- { text: "Guide", link: "/guide" },
- { text: "Cookbook", link: "/cookbook/integrating-shadcn-ui" },
- {
- text: "Links",
- items: [
- { text: "Official Inertia.js docs", link: "https://inertiajs.com" },
- {
- text: "Gems",
- items: [
- {
- text: "inertia_rails",
- link: "https://github.com/inertiajs/inertia-rails",
- },
- {
- text: "inertia_rails-contrib",
- link: "https://github.com/skryukov/inertia_rails-contrib",
- },
- ],
- },
- ],
- },
- ],
-
- logo: "/logo.svg",
-
- sidebar: {
- "/guide": [
- {
- items: [
- { text: "Introduction", link: "/guide" },
- { text: "Demo app", link: "/guide/demo-application" },
- ],
- },
- {
- text: "Installation",
- items: [
- { text: "Server-side", link: "/guide/server-side-setup" },
- { text: "Client-side", link: "/guide/client-side-setup" },
- ],
- },
- {
- text: "Core concepts",
- items: [
- { text: "Who is it for", link: "/guide/who-is-it-for" },
- { text: "How it works", link: "/guide/how-it-works" },
- { text: "The protocol", link: "/guide/the-protocol" },
- ],
- },
- {
- text: "The basics",
- items: [
- { text: "Pages", link: "/guide/pages" },
- { text: "Responses", link: "/guide/responses" },
- { text: "Redirects", link: "/guide/redirects" },
- { text: "Routing", link: "/guide/routing" },
- { text: "Title & meta", link: "/guide/title-and-meta" },
- { text: "Links", link: "/guide/links" },
- { text: "Manual visits", link: "/guide/manual-visits" },
- { text: "Forms", link: "/guide/forms" },
- { text: "File uploads", link: "/guide/file-uploads" },
- { text: "Validation", link: "/guide/validation" },
- { text: "Shared data", link: "/guide/shared-data" },
- ],
- },
- {
- text: "Advanced",
- items: [
- { text: "Events", link: "/guide/events" },
- { text: "Testing", link: "/guide/testing" },
- { text: "Partial reloads", link: "/guide/partial-reloads" },
- { text: "Scroll management", link: "/guide/scroll-management" },
- { text: "Authentication", link: "/guide/authentication" },
- { text: "Authorization", link: "/guide/authorization" },
- { text: "CSRF protection", link: "/guide/csrf-protection" },
- { text: "Error handling", link: "/guide/error-handling" },
- { text: "Asset versioning", link: "/guide/asset-versioning" },
- { text: "Progress indicators", link: "/guide/progress-indicators" },
- { text: "Remembering state", link: "/guide/remembering-state" },
- { text: "Code splitting", link: "/guide/code-splitting" },
- {
- text: "Server-side rendering",
- link: "/guide/server-side-rendering",
- },
- ],
- },
- ],
- "/cookbook": [
- {
- items: [
- {
- text: "Integrations",
- items: [
- { text: "shadcn/ui", link: "/cookbook/integrating-shadcn-ui" },
- ],
- },
- ],
- },
- ],
- },
-
- search: {
- provider: "algolia",
- options: {
- appId: "NFLARHZ4Q4",
- apiKey: "5e79b6038b027b5bb342ea5a31d0a2e8",
- indexName: "inertia-rails",
- },
- },
-
- editLink: {
- pattern:
- "https://github.com/skryukov/inertia_rails-contrib/edit/main/docs/:path",
- text: "Edit this page on GitHub",
- },
-
- socialLinks: [
- { icon: "github", link: "https://github.com/inertiajs/inertia-rails" },
- { icon: "x", link: "https://x.com/inertiajs" },
- { icon: "discord", link: "https://discord.gg/inertiajs" },
- ],
- },
-});
diff --git a/docs/.vitepress/theme/frameworksTabs.ts b/docs/.vitepress/theme/frameworksTabs.ts
deleted file mode 100644
index 4868801..0000000
--- a/docs/.vitepress/theme/frameworksTabs.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-const localStorageKey = "vitepress:tabsSharedState";
-const ls = typeof localStorage !== "undefined" ? localStorage : null;
-
-const getLocalStorageValue = (): Record => {
- const rawValue = ls?.getItem(localStorageKey);
- if (rawValue) {
- try {
- return JSON.parse(rawValue);
- } catch {}
- }
- return {};
-};
-
-const setLocalStorageValue = (v: Record) => {
- if (!ls) return;
- ls.setItem(localStorageKey, JSON.stringify(v));
-};
-
-export const setupFrameworksTabs = () => {
- const v = getLocalStorageValue();
- if (!v.frameworks) {
- setLocalStorageValue({ frameworks: "React" });
- }
-};
diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts
deleted file mode 100644
index b21c9a1..0000000
--- a/docs/.vitepress/theme/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-// https://vitepress.dev/guide/custom-theme
-import { h } from "vue";
-import type { Theme } from "vitepress";
-import DefaultTheme from "vitepress/theme";
-import { enhanceAppWithTabs } from "vitepress-plugin-tabs/client";
-import { setupFrameworksTabs } from "./frameworksTabs";
-import "./style.css";
-
-export default {
- extends: DefaultTheme,
- Layout: () => {
- return h(DefaultTheme.Layout, null, {
- // https://vitepress.dev/guide/extending-default-theme#layout-slots
- });
- },
- enhanceApp({ app, router, siteData }) {
- enhanceAppWithTabs(app);
- },
- setup() {
- setupFrameworksTabs();
- },
-} satisfies Theme;
diff --git a/docs/.vitepress/theme/style.css b/docs/.vitepress/theme/style.css
deleted file mode 100644
index 83bf35e..0000000
--- a/docs/.vitepress/theme/style.css
+++ /dev/null
@@ -1,175 +0,0 @@
-/**
- * Customize default theme styling by overriding CSS variables:
- * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css
- */
-
-/**
- * Colors
- *
- * Each colors have exact same color scale system with 3 levels of solid
- * colors with different brightness, and 1 soft color.
- *
- * - `XXX-1`: The most solid color used mainly for colored text. It must
- * satisfy the contrast ratio against when used on top of `XXX-soft`.
- *
- * - `XXX-2`: The color used mainly for hover state of the button.
- *
- * - `XXX-3`: The color for solid background, such as bg color of the button.
- * It must satisfy the contrast ratio with pure white (#ffffff) text on
- * top of it.
- *
- * - `XXX-soft`: The color used for subtle background such as custom container
- * or badges. It must satisfy the contrast ratio when putting `XXX-1` colors
- * on top of it.
- *
- * The soft color must be semi transparent alpha channel. This is crucial
- * because it allows adding multiple "soft" colors on top of each other
- * to create a accent, such as when having inline code block inside
- * custom containers.
- *
- * - `default`: The color used purely for subtle indication without any
- * special meanings attched to it such as bg color for menu hover state.
- *
- * - `brand`: Used for primary brand colors, such as link text, button with
- * brand theme, etc.
- *
- * - `tip`: Used to indicate useful information. The default theme uses the
- * brand color for this by default.
- *
- * - `warning`: Used to indicate warning to the users. Used in custom
- * container, badges, etc.
- *
- * - `danger`: Used to show error, or dangerous message to the users. Used
- * in custom container, badges, etc.
- * -------------------------------------------------------------------------- */
-
-:root {
- --vp-c-default-1: var(--vp-c-gray-1);
- --vp-c-default-2: var(--vp-c-gray-2);
- --vp-c-default-3: var(--vp-c-gray-3);
- --vp-c-default-soft: var(--vp-c-gray-soft);
-
- --vp-c-brand-1: var(--vp-c-purple-1);
- --vp-c-brand-2: var(--vp-c-purple-2);
- --vp-c-brand-3: var(--vp-c-purple-3);
- --vp-c-brand-soft: var(--vp-c-purple-soft);
-
- --vp-c-tip-1: var(--vp-c-brand-1);
- --vp-c-tip-2: var(--vp-c-brand-2);
- --vp-c-tip-3: var(--vp-c-brand-3);
- --vp-c-tip-soft: var(--vp-c-brand-soft);
-
- --vp-c-warning-1: var(--vp-c-yellow-1);
- --vp-c-warning-2: var(--vp-c-yellow-2);
- --vp-c-warning-3: var(--vp-c-yellow-3);
- --vp-c-warning-soft: var(--vp-c-yellow-soft);
-
- --vp-c-danger-1: var(--vp-c-red-1);
- --vp-c-danger-2: var(--vp-c-red-2);
- --vp-c-danger-3: var(--vp-c-red-3);
- --vp-c-danger-soft: var(--vp-c-red-soft);
-}
-
-/**
- * Component: Button
- * -------------------------------------------------------------------------- */
-
-:root {
- --vp-button-brand-border: transparent;
- --vp-button-brand-text: var(--vp-c-white);
- --vp-button-brand-bg: var(--vp-c-brand-3);
- --vp-button-brand-hover-border: transparent;
- --vp-button-brand-hover-text: var(--vp-c-white);
- --vp-button-brand-hover-bg: var(--vp-c-brand-2);
- --vp-button-brand-active-border: transparent;
- --vp-button-brand-active-text: var(--vp-c-white);
- --vp-button-brand-active-bg: var(--vp-c-brand-1);
-}
-
-/**
- * Component: Home
- * -------------------------------------------------------------------------- */
-
-:root {
- --vp-home-hero-name-color: transparent;
- --vp-home-hero-name-background: -webkit-linear-gradient(
- 0deg,
- #9553e9,
- #6d74ed
- );
-
- --vp-home-hero-image-background-image: linear-gradient(
- -45deg,
- #9553e9 50%,
- #6d74ed 50%
- );
- --vp-home-hero-image-filter: blur(44px);
-}
-
-@media (min-width: 640px) {
- :root {
- --vp-home-hero-image-filter: blur(56px);
- }
-}
-
-@media (min-width: 960px) {
- :root {
- --vp-home-hero-image-filter: blur(68px);
- }
-}
-
-/**
- * Component: Custom Block
- * -------------------------------------------------------------------------- */
-
-:root {
- --vp-custom-block-tip-border: transparent;
- --vp-custom-block-tip-text: var(--vp-c-text-1);
- --vp-custom-block-tip-bg: var(--vp-c-brand-soft);
- --vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);
-}
-
-/**
- * Component: Algolia
- * -------------------------------------------------------------------------- */
-
-.DocSearch {
- --docsearch-primary-color: var(--vp-c-brand-1) !important;
-}
-
-/**
- * Component: Tabs
- * -------------------------------------------------------------------------- */
-
-.plugin-tabs {
- background-color: initial !important;
-}
-
-.plugin-tabs--tab-list {
- background-color: var(--vp-code-block-bg);
-}
-
-.plugin-tabs--content {
- padding: 0 !important;
-}
-
-.plugin-tabs--content div[class*="language-"] {
- background-color: var(--vp-code-block-bg) !important;
-}
-
-.plugin-tabs--content div[class*="language-"]:first-child {
- border-top-left-radius: 0 !important;
- border-top-right-radius: 0 !important;
-}
-
-.plugin-tabs--content:has(> p:first-child) {
- border-left: 2px solid var(--vp-c-divider) !important;
- border-right: 2px solid var(--vp-c-divider) !important;
- border-bottom: 2px solid var(--vp-c-divider) !important;
- padding: 8px !important;
-}
-
-.plugin-tabs--content:has(> p:first-child) p {
- margin-top: 16px !important;
- padding-left: 16px;
-}
diff --git a/docs/cookbook/integrating-shadcn-ui.md b/docs/cookbook/integrating-shadcn-ui.md
deleted file mode 100644
index f80de12..0000000
--- a/docs/cookbook/integrating-shadcn-ui.md
+++ /dev/null
@@ -1,136 +0,0 @@
-# Integrating `shadcn/ui`
-
-This guide demonstrates how to integrate [shadcn/ui](https://ui.shadcn.com) - a collection of reusable React components - with your Inertia Rails application.
-
-## Getting Started in 5 Minutes
-
-If you're starting fresh, create a new Rails application with Inertia (or skip this step if you already have one):
-
-:::tabs key:languages
-
-== TypeScript
-
-```bash
-rails new -JA shadcn-inertia-rails
-cd shadcn-inertia-rails
-bundle add inertia_rails-contrib
-
-rails generate inertia:install --framework=react --typescript --install-vite --install-tailwind --no-interactive
-Installing Inertia's Rails adapter
-...
-```
-
-== JavaScript
-
-```bash
-rails new -JA shadcn-inertia-rails
-cd shadcn-inertia-rails
-bundle add inertia_rails-contrib
-
-rails generate inertia:install --framework=react --install-vite --install-tailwind --no-interactive
-Installing Inertia's Rails adapter
-...
-```
-
-:::
-
-> [!NOTE]
-> You can also run `rails generate inertia:install` to run the installer interactively.
-> Need more details on the initial setup? Check out our [server-side setup guide](/guide/server-side-setup.md).
-
-## Setting Up Path Aliases
-
-Let's configure our project to work seamlessly with `shadcn/ui`. Choose your path based on whether you're using TypeScript or JavaScript.
-
-
-:::tabs key:languages
-
-== TypeScript
-
-You'll need to configure two files. First, update your `tsconfig.app.json`:
-
-```json5
-{
- "compilerOptions": {
- // ...
- "baseUrl": ".",
- "paths": {
- "@/*": [
- "./app/frontend/*"
- ]
- }
- },
- // ...
-}
-```
-
-Then, set up your `tsconfig.json` to match `shadcn/ui`'s requirements (note the `baseUrl` and `paths` properties are different from the `tsconfig.app.json`):
-
-```json5
-{
- //...
- "compilerOptions": {
- /* Required for shadcn-ui/ui */
- "baseUrl": "./app/frontend",
- "paths": {
- "@/*": [
- "./*"
- ]
- }
- }
-}
-```
-
-== JavaScript
-
-Using JavaScript? It's even simpler! Just create a `jsconfig.json`:
-
-```json
-{
- "compilerOptions": {
- "baseUrl": "./app/frontend",
- "paths": {
- "@/*": ["./*"]
- }
- }
-}
-```
-
-:::
-
-## Initializing `shadcn/ui`
-
-Now you can initialize `shadcn/ui` with a single command:
-
-```bash
-npx shadcn@latest init
-
-✔ Preflight checks.
-✔ Verifying framework. Found Vite.
-✔ Validating Tailwind CSS.
-✔ Validating import alias.
-✔ Which style would you like to use? › New York
-✔ Which color would you like to use as the base color? › Neutral
-✔ Would you like to use CSS variables for theming? … no / yes
-✔ Writing components.json.
-✔ Checking registry.
-✔ Updating tailwind.config.js
-✔ Updating app/frontend/entrypoints/application.css
-✔ Installing dependencies.
-✔ Created 1 file:
- - app/frontend/lib/utils.js
-
-Success! Project initialization completed.
-You may now add components.
-```
-
-You're all set! Want to try it out? Add your first component:
-
-```shell
-npx shadcn@latest add button
-```
-
-Now you can import and use your new button component from `@/components/ui/button`. Happy coding!
-
-> [!NOTE]
-> Check out the [`shadcn/ui` components gallery](https://ui.shadcn.com/docs/components/accordion) to explore all the beautiful components at your disposal.
diff --git a/docs/guide/asset-versioning.md b/docs/guide/asset-versioning.md
deleted file mode 100644
index 18f48e2..0000000
--- a/docs/guide/asset-versioning.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# Asset versioning
-
-One common challenge when building single-page apps is refreshing site assets when they've been changed. Thankfully, Inertia makes this easy by optionally tracking the current version of your site assets. When an asset changes, Inertia will automatically make a full page visit instead of a XHR visit on the next request.
-
-## Configuration
-
-To enable automatic asset refreshing, you need to tell Inertia the current version of your assets. This can be any arbitrary string (letters, numbers, or a file hash), as long as it changes when your assets have been updated.
-
-```ruby
-InertiaRails.configure do |config|
- config.version = ViteRuby.digest # or any other versioning method
-end
-
-# You can also use lazy evaluation
-InertiaRails.configure do |config|
- config.version = lambda { ViteRuby.digest }
-end
-```
-
-## Cache busting
-
-Asset refreshing in Inertia works on the assumption that a hard page visit will trigger your assets to reload. However, Inertia doesn't actually do anything to force this. Typically this is done with some form of cache busting. For example, appending a version query parameter to the end of your asset URLs.
diff --git a/docs/guide/authentication.md b/docs/guide/authentication.md
deleted file mode 100644
index 0eafb2c..0000000
--- a/docs/guide/authentication.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Authentication
-
-One of the benefits of using Inertia is that you don't need a special authentication system such as OAuth to connect to your data provider (API). Also, since your data is provided via your controllers, and housed on the same domain as your JavaScript components, you don't have to worry about setting up CORS.
-
-Rather, when using Inertia, you can simply use whatever authentication system you like, such as solutions based on Rails' built-in `has_secure_password` method, or gems like [Devise](https://github.com/heartcombo/devise), [Sorcery](https://github.com/Sorcery/sorcery), [Authentication Zero](https://github.com/lazaronixon/authentication-zero), etc.
diff --git a/docs/guide/authorization.md b/docs/guide/authorization.md
deleted file mode 100644
index 07021b0..0000000
--- a/docs/guide/authorization.md
+++ /dev/null
@@ -1,28 +0,0 @@
-# Authorization
-
-When using Inertia, authorization is best handled server-side in your application's authorization policies. However, you may be wondering how to perform checks against your authorization policies from within your Inertia page components since you won't have access to your framework's server-side helpers.
-
-The simplest approach to solving this problem is to pass the results of your authorization checks as props to your page components.
-
-Here's an example of how you might do this in a Rails controller using the [Action Policy](https://github.com/palkan/action_policy) gem:
-
-```ruby
-class UsersController < ApplicationController
- def index
- render inertia: 'Users/Index', props: {
- can: {
- create_user: allowed_to?(:create, User)
- },
- users: User.all.map do |user|
- user.as_json(
- only: [:id, :first_name, :last_name, :email]
- ).merge(
- can: {
- edit_user: allowed_to?(:edit, user)
- }
- )
- end
- }
- end
-end
-```
diff --git a/docs/guide/client-side-setup.md b/docs/guide/client-side-setup.md
deleted file mode 100644
index 216f979..0000000
--- a/docs/guide/client-side-setup.md
+++ /dev/null
@@ -1,229 +0,0 @@
-# Client-side setup
-
-Once you have your [server-side framework configured](/guide/server-side-setup.md), you then need to setup your client-side framework. Inertia currently provides support for React, Vue, and Svelte.
-
-> [!NOTE]
-> See [Rails generator](/guide/server-side-setup#rails-generator) for a quick way to setup Inertia in your Rails application.
-
-## Install dependencies
-
-First, install the Inertia client-side adapter corresponding to your framework of choice.
-
-:::tabs key:frameworks
-== Vue 2
-
-```shell
-npm install @inertiajs/vue2 vue@^2
-```
-
-== Vue 3
-
-```shell
-npm install @inertiajs/vue3 vue
-```
-
-== React
-
-```shell
-npm install @inertiajs/react react react-dom
-```
-
-== Svelte
-
-```shell
-npm install @inertiajs/svelte svelte
-```
-
-:::
-
-## Initialize the Inertia app
-
-Next, update your main JavaScript file to boot your Inertia app. To accomplish this, we'll initialize the client-side framework with the base Inertia component.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-// frontend/entrypoints/inertia.js
-import Vue from 'vue'
-import { createInertiaApp } from '@inertiajs/vue2'
-
-createInertiaApp({
- resolve: (name) => {
- const pages = import.meta.glob('../pages/**/*.vue', { eager: true })
- return pages[`../pages/${name}.vue`]
- },
- setup({ el, App, props, plugin }) {
- Vue.use(plugin)
-
- new Vue({
- render: (h) => h(App, props),
- }).$mount(el)
- },
-})
-```
-
-== Vue 3
-
-```js
-// frontend/entrypoints/inertia.js
-import { createApp, h } from 'vue'
-import { createInertiaApp } from '@inertiajs/vue3'
-
-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)
- },
-})
-```
-
-== React
-
-```js
-// frontend/entrypoints/inertia.js
-import { createInertiaApp } from '@inertiajs/react'
-import { createElement } from 'react'
-import { createRoot } from 'react-dom/client'
-
-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))
- },
-})
-```
-
-== Svelte
-
-```js
-// frontend/entrypoints/inertia.js
-import { createInertiaApp } from '@inertiajs/svelte'
-
-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 })
- },
-})
-```
-
-:::
-
-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.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-// Vite
-// frontend/entrypoints/inertia.js
-createInertiaApp({
- resolve: name => {
- const pages = import.meta.glob('../pages/**/*.vue', {eager: true})
- return pages[`../pages/${name}.vue`]
- },
- // ...
-})
-
-// Webpacker/Shakapacker
-// javascript/packs/inertia.js
-createInertiaApp({
- resolve: name => require(`../pages/${name}`),
- // ...
-})
-```
-
-== Vue 3
-
-```js
-// Vite
-// frontend/entrypoints/inertia.js
-createInertiaApp({
- resolve: name => {
- const pages = import.meta.glob('../pages/**/*.vue', { eager: true })
- return pages[`../pages/${name}.vue`]
- },
- // ...
-})
-
-// Webpacker/Shakapacker
-// javascript/packs/inertia.js
-createInertiaApp({
- resolve: name => require(`../pages/${name}`),
- // ...
-})
-```
-
-== React
-
-```js
-// Vite
-// frontend/entrypoints/inertia.js
-createInertiaApp({
- resolve: name => {
- const pages = import.meta.glob('../pages/**/*.jsx', {eager: true})
- return pages[`../pages/${name}.jsx`]
- },
- //...
-})
-
-// Webpacker/Shakapacker
-// javascript/packs/inertia.js
-createInertiaApp({
- resolve: name => require(`../pages/${name}`),
- //...
-})
-```
-
-== Svelte
-
-```js
-// Vite
-// frontend/entrypoints/inertia.js
-createInertiaApp({
- resolve: name => {
- const pages = import.meta.glob('../pages/**/*.svelte', {eager: true})
- return pages[`../pages/${name}.svelte`]
- },
- //...
-})
-
-// Webpacker/Shakapacker
-// javascript/packs/inertia.js
-createInertiaApp({
- resolve: name => require(`../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](/guide/code-splitting.md) documentation.
-
-## Defining a root element
-
-By default, Inertia assumes that your application's root template has a root element with an `id` of `app`. If your application's root element has a different `id`, you can provide it using the `id` property.
-
-```js
-createInertiaApp({
- id: 'my-app',
- // ...
-})
-```
diff --git a/docs/guide/code-splitting.md b/docs/guide/code-splitting.md
deleted file mode 100644
index c664251..0000000
--- a/docs/guide/code-splitting.md
+++ /dev/null
@@ -1,155 +0,0 @@
-# Code splitting
-
-Code splitting breaks apart the various pages of your application into smaller bundles, which are then loaded on demand when visiting new pages. This can significantly reduce the size of the initial JavaScript bundle loaded by the browser, improving the time to first render.
-
-While code splitting is helpful for very large projects, it does require extra requests when visiting new pages. Generally speaking, if you're able to use a single bundle, your app is going to feel snappier.
-
-To enable code splitting you'll need to tweak the resolve callback in your `createInertiaApp()` configuration, and how you do this is different depending on which bundler you're using.
-
-## Using Vite
-
-Vite enables code splitting (or lazy-loading as they call it) by default when using their `import.meta.glob()` function, so simply omit the `{ eager: true }` option, or set it to false, to disable eager loading.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-// frontend/entrypoints/inertia.js
-createInertiaApp({
- resolve: name => {
- const pages = import.meta.glob('../pages/**/*.vue', {eager: true}) // [!code --]
- return pages[`../pages/${name}.vue`] // [!code --]
- const pages = import.meta.glob('../pages/**/*.vue') // [!code ++]
- return pages[`../pages/${name}.vue`]() // [!code ++]
- },
- //...
-})
-```
-
-== Vue 3
-
-```js
-// frontend/entrypoints/inertia.js
-createInertiaApp({
- resolve: name => {
- const pages = import.meta.glob('../pages/**/*.vue', { eager: true }) // [!code --]
- return pages[`../pages/${name}.vue`] // [!code --]
- const pages = import.meta.glob('../pages/**/*.vue') // [!code ++]
- return pages[`../pages/${name}.vue`]() // [!code ++]
- },
- //...
-})
-```
-
-== React
-
-```js
-// frontend/entrypoints/inertia.js
-createInertiaApp({
- resolve: name => {
- const pages = import.meta.glob('../pages/**/*.jsx', { eager: true }) // [!code --]
- return pages[`../pages/${name}.jsx`] // [!code --]
- const pages = import.meta.glob('../pages/**/*.jsx') // [!code ++]
- return pages[`../pages/${name}.jsx`]() // [!code ++]
- },
- //...
-})
-```
-
-== Svelte
-
-```js
-// frontend/entrypoints/inertia.js
-createInertiaApp({
- resolve: name => {
- const pages = import.meta.glob('../pages/**/*.svelte', { eager: true }) // [!code --]
- return pages[`../pages/${name}.svelte`] // [!code --]
- const pages = import.meta.glob('../pages/**/*.svelte') // [!code ++]
- return pages[`../pages/${name}.svelte`]() // [!code ++]
- },
- //...
-})
-```
-
-:::
-
-## Using Webpacker/Shakapacker
-
-> [!WARNING]
-> We recommend using [Vite Ruby](https://vite-ruby.netlify.app) for new projects.
-
-To use code splitting with Webpack, you will first need to enable [dynamic imports](https://github.com/tc39/proposal-dynamic-import) via a Babel plugin. Let's install it now.
-
-```shell
-npm install @babel/plugin-syntax-dynamic-import
-```
-
-Next, create a `.babelrc` file in your project with the following configuration:
-
-```json
-{
- "plugins": ["@babel/plugin-syntax-dynamic-import"]
-}
-```
-
-Finally, update the `resolve` callback in your app's initialization code to use `import` instead of `require`.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-// javascript/packs/inertia.js
-createInertiaApp({
- resolve: name => require(`../pages/${name}`), // [!code ii]
- resolve: name => import(`../pages/${name}`), // [!code ++]
- //...
-})
-```
-
-== Vue 3
-
-```js
-// javascript/packs/inertia.js
-createInertiaApp({
- resolve: name => require(`../pages/${name}`), // [!code ii]
- resolve: name => import(`../pages/${name}`), // [!code ++]
- //...
-})
-```
-
-== React
-
-```js
-// javascript/packs/inertia.js
-createInertiaApp({
- resolve: name => require(`../pages/${name}`), // [!code ii]
- resolve: name => import(`../pages/${name}`), // [!code ++]
- //...
-})
-```
-
-== Svelte
-
-```js
-// javascript/packs/inertia.js
-createInertiaApp({
- resolve: name => require(`../pages/${name}.svelte`), // [!code ii]
- resolve: name => import(`../pages/${name}.svelte`), // [!code ++]
- //...
-})
-```
-
-:::
-
-You should also consider using cache busting to force browsers to load the latest version of your assets. To accomplish this, add the following configuration to your webpack configuration file.
-
-```js
-// webpack.config.js
-module.exports = {
- //...
- output: {
- //...
- chunkFilename: 'js/[name].js?id=[chunkhash]',
- },
-}
-```
diff --git a/docs/guide/csrf-protection.md b/docs/guide/csrf-protection.md
deleted file mode 100644
index 81df703..0000000
--- a/docs/guide/csrf-protection.md
+++ /dev/null
@@ -1,94 +0,0 @@
-# CSRF protection
-
-## Making requests
-
-Inertia's Rails adapter automatically includes the proper CSRF token when making requests via Inertia or Axios. Therefore, **no additional configuration is required**.
-
-However, if you need to handle CSRF protection manually, one approach is to include the CSRF token as a prop on every response. You can then use the token when making Inertia requests.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.post('/users', {
- _token: this.$page.props.csrf_token,
- name: 'John Doe',
- email: 'john.doe@example.com',
-})
-```
-
-== Vue 3
-
-```js
-import { router, usePage } from '@inertiajs/vue3'
-
-const page = usePage()
-
-router.post('/users', {
- _token: page.props.csrf_token,
- name: 'John Doe',
- email: 'john.doe@example.com',
-})
-```
-
-== React
-
-```js
-import { router, usePage } from '@inertiajs/react'
-
-const props = usePage().props
-
-router.post('/users', {
- _token: props.csrf_token,
- name: 'John Doe',
- email: 'john.doe@example.com',
-})
-```
-
-== Svelte
-
-```js
-import { page, router } from '@inertiajs/svelte'
-
-router.post('/users', {
- _token: $page.props.csrf_token,
- name: 'John Doe',
- email: 'john.doe@example.com',
-})
-```
-
-:::
-
-You can even use Inertia's [shared data](/guide/shared-data.md) functionality to automatically include the `csrf_token` with each response.
-
-However, a better approach is to use the CSRF functionality already built into [axios](https://github.com/axios/axios) for this. Axios is the HTTP library that Inertia uses under the hood.
-
-Axios automatically checks for the existence of an `XSRF-TOKEN` cookie. If it's present, it will then include the token in an `X-XSRF-TOKEN` header for any requests it makes.
-
-The easiest way to implement this is using server-side middleware. Simply include the `XSRF-TOKEN` cookie on each response, and then verify the token using the `X-XSRF-TOKEN` header sent in the requests from axios. (That's basically what `inertia_rails` does).
-
-## Handling mismatches
-
-When a CSRF token mismatch occurs, Rails raises the `ActionController::InvalidAuthenticityToken` error. Since that isn't a valid Inertia response, the error is shown in a modal.
-
-Obviously, this isn't a great user experience. A better way to handle these errors is to return a redirect back to the previous page, along with a flash message that the page expired. This will result in a valid Inertia response with the flash message available as a prop which you can then display to the user. Of course, you'll need to share your [flash messages](/guide/shared-data.md#flash-messages) with Inertia for this to work.
-
-You may modify your application's exception handler to automatically redirect the user back to the page they were previously on while flashing a message to the session. To accomplish this, you may use the `rescue_from` method in your `ApplicationController`.
-
-```ruby
-class ApplicationController < ActionController::Base
- rescue_from ActionController::InvalidAuthenticityToken, with: :inertia_page_expired_error
-
- inertia_share flash: -> { flash.to_hash }
-
- private
-
- def inertia_page_expired_error
- redirect_back_or_to('/', allow_other_host: false, notice: "The page expired, please try again.")
- end
-end
-```
-
-The end result is a much better experience for your users. Instead of seeing the error modal, the user is instead presented with a message that the page "expired" and are asked to try again.
diff --git a/docs/guide/demo-application.md b/docs/guide/demo-application.md
deleted file mode 100644
index cf9edde..0000000
--- a/docs/guide/demo-application.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Demo application
-
-We've setup a demo app for Inertia.js called [Ping CRM](https://demo.inertiajs.com/login). This application is built using Laravel and Vue. You can find the source code on [GitHub](https://github.com/inertiajs/pingcrm).
-
-> [!NOTE]
-> The Ping CRM demo is hosted on Heroku and the database is reset every hour. Please be respectful when editing data.
-
-[![Ping CRM demo](/pingcrm.png)](https://demo.inertiajs.com/login)
-
-In addition to the Vue version of Ping CRM, we also maintain a Svelte version of the application, which you can find [on GitHub](https://github.com/inertiajs/pingcrm-svelte).
-
-## Third party
-
-Beyond our official demo app, Ping CRM has also been translated into numerous different languages and frameworks.
-
-- [Ruby on Rails/Vue](https://github.com/ledermann/pingcrm) by Georg Ledermann
-- [Ruby on Rails/Vue SSR/Vite](https://github.com/ElMassimo/pingcrm-vite) by Máximo Mussini
-- [Laravel/React](https://github.com/Landish/pingcrm-react) by Lado Lomidze
-- [Laravel/Svelte](https://github.com/zgabievi/pingcrm-svelte) by Zura G]abievi
-- [Laravel/Mithril.js](https://github.com/tbreuss/pingcrm-mithril) by Thomas Breuss
-- [Yii 2/Vue](https://github.com/tbreuss/pingcrm-yii2) by Thomas Breuss
-- [Symfony/Vue](https://github.com/aleksblendwerk/pingcrm-symfony) by Aleks Seltenreich
-- [Clojure/React](https://github.com/prestancedesign/pingcrm-clojure) by Michaël Salihi
diff --git a/docs/guide/error-handling.md b/docs/guide/error-handling.md
deleted file mode 100644
index 05a19a7..0000000
--- a/docs/guide/error-handling.md
+++ /dev/null
@@ -1,167 +0,0 @@
-# Error handling
-
-## Development
-
-One of the advantages to working with a robust server-side framework is the built-in exception handling you get for free. The challenge is, if you're making an XHR request (which Inertia does) and you hit a server-side error, you're typically left digging through the network tab in your browser's devtools to diagnose the problem.
-
-Inertia solves this issue by showing all non-Inertia responses in a modal. This means you get the same beautiful error-reporting you're accustomed to, even though you've made that request over XHR.
-
-## Production
-
-In production you will want to return a proper Inertia error response instead of relying on the modal-driven error reporting that is present during development. To accomplish this, you'll need to update your framework's default exception handler to return a custom error page.
-
-When building Rails applications, you can accomplish this by using the `rescue_from` method in your `ApplicationController`.
-
-```ruby
-class ApplicationController < ActionController::Base
- rescue_from StandardError, with: :inertia_error_page
-
- private
-
- def inertia_error_page(exception)
- raise exception if Rails.env.local?
-
- status = ActionDispatch::ExceptionWrapper.new(nil, exception).status_code
-
- render inertia: 'Error', props: { status: }, status:
- end
-end
-```
-
-You may have noticed we're returning an `Error` page component in the example above. You'll need to actually create this component, which will serve as the generic error page for your application. Here's an example error component you can use as a starting point.
-
-:::tabs key:frameworks
-== Vue 2
-
-```vue
-
-
-
{{ status }}: {{ title }}
-
{{ description }}
-
-
-
-
-```
-
-== Vue 3
-
-```vue
-
-
-
-
-
{{ status }}: {{ title }}
-
{{ description }}
-
-
-```
-
-== React
-
-```jsx
-export default function ErrorPage({ status }) {
- const title =
- {
- 503: 'Service Unavailable',
- 500: 'Server Error',
- 404: 'Page Not Found',
- 403: 'Forbidden',
- }[status] || 'Unexpected error'
-
- const description = {
- 503: 'Sorry, we are doing some maintenance. Please check back soon.',
- 500: 'Whoops, something went wrong on our servers.',
- 404: 'Sorry, the page you are looking for could not be found.',
- 403: 'Sorry, you are forbidden from accessing this page.',
- }[status]
-
- return (
-
-
- {status}: {title}
-
-
{description}
-
- )
-}
-```
-
-== Svelte
-
-```svelte
-
-
-
-
{status}: {title}
-
{description}
-
-```
-
-:::
diff --git a/docs/guide/events.md b/docs/guide/events.md
deleted file mode 100644
index 3afdfc7..0000000
--- a/docs/guide/events.md
+++ /dev/null
@@ -1,980 +0,0 @@
-# Events
-
-Inertia provides an event system that allows you to "hook into" the various lifecycle events of the library.
-
-## Registering listeners
-
-To register an event listener, use the `router.on()` method.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-```
-
-:::
-
-Under the hood, Inertia uses native browser events, so you can also interact with Inertia events using the typical event methods you may already be familiar with - just be sure to prepend `inertia:` to the event name.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-document.addEventListener('inertia:start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-document.addEventListener('inertia:start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-document.addEventListener('inertia:start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-document.addEventListener('inertia:start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-```
-
-:::
-
-## Removing listeners
-
-When you register an event listener, Inertia automatically returns a callback that can be invoked to remove the event listener.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-let removeStartEventListener = router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-
-// Remove the listener...
-removeStartEventListener()
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-let removeStartEventListener = router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-
-// Remove the listener...
-removeStartEventListener()
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-let removeStartEventListener = router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-
-// Remove the listener...
-removeStartEventListener()
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-let removeStartEventListener = router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-
-// Remove the listener...
-removeStartEventListener()
-```
-
-:::
-
-Combined with hooks, you can automatically remove the event listener when components unmount.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-export default {
- mounted() {
- this.$once(
- 'hook:destroyed',
- router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
- }),
- )
- },
-}
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-import { onUnmounted } from 'vue'
-
-onUnmounted(
- router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
- }),
-)
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-import { useEffect } from 'react'
-
-useEffect(() => {
- return router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
- })
-}, [])
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-import { onMount } from 'svelte'
-
-onMount(() => {
- return router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
- })
-})
-```
-
-:::
-
-Alternatively, if you're using native browser events, you can remove the event listener using `removeEventListener()`.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-let startEventListener = (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-}
-
-document.addEventListener('inertia:start', startEventListener)
-
-// Remove the listener...
-document.removeEventListener('inertia:start', startEventListener)
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-let startEventListener = (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-}
-
-document.addEventListener('inertia:start', startEventListener)
-
-// Remove the listener...
-document.removeEventListener('inertia:start', startEventListener)
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-let startEventListener = (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-}
-
-document.addEventListener('inertia:start', startEventListener)
-
-// Remove the listener...
-document.removeEventListener('inertia:start', startEventListener)
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-let startEventListener = (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-}
-
-document.addEventListener('inertia:start', startEventListener)
-
-// Remove the listener...
-document.removeEventListener('inertia:start', startEventListener)
-```
-
-:::
-
-## Cancelling events
-
-Some events, such as `before`, `invalid`, and `error`, support cancellation, allowing you to prevent Inertia's default behavior. Just like native events, the event will be cancelled if only one event listener calls `event.preventDefault()`.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('before', (event) => {
- if (!confirm('Are you sure you want to navigate away?')) {
- event.preventDefault()
- }
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('before', (event) => {
- if (!confirm('Are you sure you want to navigate away?')) {
- event.preventDefault()
- }
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('before', (event) => {
- if (!confirm('Are you sure you want to navigate away?')) {
- event.preventDefault()
- }
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('before', (event) => {
- if (!confirm('Are you sure you want to navigate away?')) {
- event.preventDefault()
- }
-})
-```
-
-:::
-
-For convenience, if you register your event listener using `router.on()`, you can cancel the event by returning `false` from the listener.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('before', (event) => {
- return confirm('Are you sure you want to navigate away?')
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('before', (event) => {
- return confirm('Are you sure you want to navigate away?')
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('before', (event) => {
- return confirm('Are you sure you want to navigate away?')
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('before', (event) => {
- return confirm('Are you sure you want to navigate away?')
-})
-```
-
-:::
-
-Note, browsers do not allow cancelling the native `popstate` event, so preventing forward and back history visits while using Inertia.js is not possible.
-
-## Before
-
-The `before` event fires when a request is about to be made to the server. This is useful for intercepting visits.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('before', (event) => {
- console.log(`About to make a visit to ${event.detail.visit.url}`)
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('before', (event) => {
- console.log(`About to make a visit to ${event.detail.visit.url}`)
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('before', (event) => {
- console.log(`About to make a visit to ${event.detail.visit.url}`)
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('before', (event) => {
- console.log(`About to make a visit to ${event.detail.visit.url}`)
-})
-```
-
-:::
-
-The primary purpose of this event is to allow you to prevent a visit from happening.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('before', (event) => {
- return confirm('Are you sure you want to navigate away?')
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('before', (event) => {
- return confirm('Are you sure you want to navigate away?')
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('before', (event) => {
- return confirm('Are you sure you want to navigate away?')
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('before', (event) => {
- return confirm('Are you sure you want to navigate away?')
-})
-```
-
-:::
-
-## Start
-
-The `start` event fires when a request to the server has started. This is useful for displaying loading indicators.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('start', (event) => {
- console.log(`Starting a visit to ${event.detail.visit.url}`)
-})
-```
-
-:::
-
-The `start` event is not cancelable.
-
-## Progress
-
-The `progress` event fires as progress increments during file uploads.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('progress', (event) => {
- this.form.progress = event.detail.progress.percentage
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('progress', (event) => {
- this.form.progress = event.detail.progress.percentage
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('progress', (event) => {
- this.form.progress = event.detail.progress.percentage
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('progress', (event) => {
- this.form.progress = event.detail.progress.percentage
-})
-```
-
-:::
-
-The `progress` event is not cancelable.
-
-## Success
-
-The `success` event fires on successful page visits, unless validation errors are present. However, this does not include history visits.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('success', (event) => {
- console.log(`Successfully made a visit to ${event.detail.page.url}`)
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('success', (event) => {
- console.log(`Successfully made a visit to ${event.detail.page.url}`)
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('success', (event) => {
- console.log(`Successfully made a visit to ${event.detail.page.url}`)
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('success', (event) => {
- console.log(`Successfully made a visit to ${event.detail.page.url}`)
-})
-```
-
-:::
-
-The `success` event is not cancelable.
-
-## Error
-
-The `error` event fires when validation errors are present on "successful" page visits.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('error', (errors) => {
- console.log(errors)
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('error', (errors) => {
- console.log(errors)
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('error', (errors) => {
- console.log(errors)
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('error', (errors) => {
- console.log(errors)
-})
-```
-
-:::
-
-The `error` event is not cancelable.
-
-## Invalid
-
-The invalid event fires when a non-Inertia response is received from the server, such as an HTML or vanilla JSON response. A valid Inertia response is a response that has the `X-Inertia` header set to `true` with a json payload containing [the page object](/guide/the-protocol.md#the-page-object).
-
-This event is fired for all response types, including `200`, `400`, and `500` response codes.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('invalid', (event) => {
- console.log(`An invalid Inertia response was received.`)
- console.log(event.detail.response)
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('invalid', (event) => {
- console.log(`An invalid Inertia response was received.`)
- console.log(event.detail.response)
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('invalid', (event) => {
- console.log(`An invalid Inertia response was received.`)
- console.log(event.detail.response)
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('invalid', (event) => {
- console.log(`An invalid Inertia response was received.`)
- console.log(event.detail.response)
-})
-```
-
-:::
-
-You may cancel the `invalid` event to prevent Inertia from showing the non-Inertia response modal.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('invalid', (event) => {
- event.preventDefault()
-
- // Handle the invalid response yourself...
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('invalid', (event) => {
- event.preventDefault()
-
- // Handle the invalid response yourself...
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('invalid', (event) => {
- event.preventDefault()
-
- // Handle the invalid response yourself...
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('invalid', (event) => {
- event.preventDefault()
-
- // Handle the invalid response yourself...
-})
-```
-
-:::
-
-## Exception
-
-The `exception` event fires on unexpected XHR errors such as network interruptions. In addition, this event fires for errors generated when resolving page components.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('exception', (event) => {
- console.log(`An unexpected error occurred during an Inertia visit.`)
- console.log(event.detail.error)
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('exception', (event) => {
- console.log(`An unexpected error occurred during an Inertia visit.`)
- console.log(event.detail.error)
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('exception', (event) => {
- console.log(`An unexpected error occurred during an Inertia visit.`)
- console.log(event.detail.error)
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('exception', (event) => {
- console.log(`An unexpected error occurred during an Inertia visit.`)
- console.log(event.detail.error)
-})
-```
-
-:::
-
-You may cancel the `exception` event to prevent the error from being thrown.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('exception', (event) => {
- event.preventDefault()
- // Handle the error yourself
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('exception', (event) => {
- event.preventDefault()
- // Handle the error yourself
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('exception', (event) => {
- event.preventDefault()
- // Handle the error yourself
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('exception', (event) => {
- event.preventDefault()
- // Handle the error yourself
-})
-```
-
-:::
-
-This event will _not_ fire for XHR requests that receive `400` and `500` level responses or for non-Inertia responses, as these situations are handled in other ways by Inertia. Please consult the [error handling](/guide/error-handling.md) documentation for more information.
-
-## Finish
-
-The `finish` event fires after an XHR request has completed for both "successful" and "unsuccessful" responses. This event is useful for hiding loading indicators.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('finish', (event) => {
- NProgress.done()
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('finish', (event) => {
- NProgress.done()
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('finish', (event) => {
- NProgress.done()
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('finish', (event) => {
- NProgress.done()
-})
-```
-
-:::
-
-The `finish` event is not cancelable.
-
-## Navigate
-
-The `navigate` event fires on successful page visits, as well as when navigating through history.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.on('navigate', (event) => {
- console.log(`Navigated to ${event.detail.page.url}`)
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.on('navigate', (event) => {
- console.log(`Navigated to ${event.detail.page.url}`)
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.on('navigate', (event) => {
- console.log(`Navigated to ${event.detail.page.url}`)
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.on('navigate', (event) => {
- console.log(`Navigated to ${event.detail.page.url}`)
-})
-```
-
-:::
-
-The `navigate` event is not cancelable.
-
-## Event callbacks
-
-In addition to the global events described throughout this page, Inertia also provides a number of [event callbacks](/guide/manual-visits.md#event-callbacks) that fire when manually making Inertia visits.
diff --git a/docs/guide/file-uploads.md b/docs/guide/file-uploads.md
deleted file mode 100644
index 5e588f1..0000000
--- a/docs/guide/file-uploads.md
+++ /dev/null
@@ -1,271 +0,0 @@
-# File uploads
-
-## FormData conversion
-
-When making Inertia requests that include files (even nested files), Inertia will automatically convert the request data into a `FormData` object. This conversion is necessary in order to submit a `multipart/form-data` request via XHR.
-
-If you would like the request to always use a `FormData` object regardless of whether a file is present in the data, you may provide the `forceFormData` option when making the request.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.post('/users', data, {
- forceFormData: true,
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.post('/users', data, {
- forceFormData: true,
-})
-```
-
-== React
-
-```jsx
-import { router } from '@inertiajs/react'
-
-router.post('/users', data, {
- forceFormData: true,
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.post('/users', data, {
- forceFormData: true,
-})
-```
-
-:::
-
-You can learn more about the `FormData` interface via its [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/FormData).
-
-> [!WARNING]
-> Prior to version 0.8.0, Inertia did not automatically convert requests to `FormData`. If you're using an Inertia release prior to this version, you will need to manually perform this conversion.
-
-## File upload example
-
-Let's examine a complete file upload example using Inertia. This example includes both a `name` text input and an `avatar` file input.
-
-:::tabs key:frameworks
-== Vue 2
-
-```vue
-
-
-
-
-
-```
-
-== Vue 3
-
-```vue
-
-
-
-
-
-```
-
-== React
-
-```jsx
-import { useForm } from '@inertiajs/react'
-
-const { data, setData, post, progress } = useForm({
- name: null,
- avatar: null,
-})
-
-function submit(e) {
- e.preventDefault()
- post('/users')
-}
-
-return (
-
-)
-```
-
-== Svelte
-
-```svelte
-
-
-
-```
-
-:::
-
-This example uses the [Inertia form helper](/guide/forms.md) for convenience, since the form helper provides easy access to the current upload progress. However, you are free to submit your forms using [manual Inertia visits](/guide/manual-visits.md) as well.
-
-## Multipart limitations
-
-Uploading files using a `multipart/form-data` request is not natively supported in some server-side frameworks when using the `PUT`, `PATCH`, or `DELETE` HTTP methods. The simplest workaround for this limitation is to simply upload files using a `POST` request instead.
-
-However, some frameworks, such as Laravel and Rails, support form method spoofing, which allows you to upload the files using `POST`, but have the framework handle the request as a `PUT` or `PATCH` request. This is done by including a `_method` attribute or a `X-HTTP-METHOD-OVERRIDE` header in the request.
-
-> [!NOTE]
-> For more info see [`Rack::MethodOverride`](https://github.com/rack/rack/blob/main/lib/rack/method_override.rb).
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-import { router } from '@inertiajs/vue2'
-
-router.post(`/users/${user.id}`, {
- _method: 'put',
- avatar: form.avatar,
-})
-
-// or
-
-form.post(`/users/${user.id}`, {
- headers: { 'X-HTTP-METHOD-OVERRIDE': 'put' },
-})
-```
-
-== Vue 3
-
-```js
-import { router } from '@inertiajs/vue3'
-
-router.post(`/users/${user.id}`, {
- _method: 'put',
- avatar: form.avatar,
-})
-
-// or
-
-form.post(`/users/${user.id}`, {
- headers: { 'X-HTTP-METHOD-OVERRIDE': 'put' },
-})
-```
-
-== React
-
-```js
-import { router } from '@inertiajs/react'
-
-router.post(`/users/${user.id}`, {
- _method: 'put',
- avatar: form.avatar,
-})
-
-// or
-
-form.post(`/users/${user.id}`, {
- headers: { 'X-HTTP-METHOD-OVERRIDE': 'put' },
-})
-```
-
-== Svelte
-
-```js
-import { router } from '@inertiajs/svelte'
-
-router.post(`/users/${user.id}`, {
- _method: 'put',
- avatar: form.avatar,
-})
-
-// or
-
-form.post(`/users/${user.id}`, {
- headers: { 'X-HTTP-METHOD-OVERRIDE': 'put' },
-})
-```
-
-:::
diff --git a/docs/guide/forms.md b/docs/guide/forms.md
deleted file mode 100644
index fb7d9d4..0000000
--- a/docs/guide/forms.md
+++ /dev/null
@@ -1,926 +0,0 @@
-# Forms
-
-## Submitting forms
-
-While it's possible to make classic HTML form submissions with Inertia, it's not recommended since they cause full-page reloads. Instead, it's better to intercept form submissions and then make the [request using Inertia](/guide/manual-visits.md).
-
-:::tabs key:frameworks
-== Vue 2
-
-```vue
-
-
-
-
-
-```
-
-== Vue 3
-
-```vue
-
-
-
-
-
-```
-
-== React
-
-```jsx
-import { useState } from 'react'
-import { router } from '@inertiajs/react'
-
-export default function Edit() {
- const [values, setValues] = useState({
- first_name: '',
- last_name: '',
- email: '',
- })
-
- function handleChange(e) {
- const key = e.target.id
- const value = e.target.value
- setValues((values) => ({
- ...values,
- [key]: value,
- }))
- }
-
- function handleSubmit(e) {
- e.preventDefault()
- router.post('/users', values)
- }
-
- return (
-
- )
-}
-```
-
-== Svelte
-
-```svelte
-
-
-
-```
-
-:::
-
-As you may have noticed in the example above, when using Inertia, you don't typically need to inspect form responses client-side like you would when making XHR / fetch requests manually.
-
-Instead, your server-side route / controller typically issues a [redirect](/guide/redirects.md) response. And, Of course, there is nothing stopping you from redirecting the user right back to the page they were previously on. Using this approach, handling Inertia form submissions feels very similar to handling classic HTML form submissions.
-
-```ruby
-class UsersController < ApplicationController
- def create
- user = User.new(user_params)
-
- if user.save
- redirect_to users_url
- else
- redirect_to new_user_url, inertia: { errors: user.errors }
- end
- end
-
- private
-
- def user_params
- params.require(:user).permit(:name, :email)
- end
-end
-```
-
-## Server-side validation
-
-Handling server-side validation errors in Inertia works a little different than handling errors from manual XHR / fetch requests. When making XHR / fetch requests, you typically inspect the response for a `422` status code and manually update the form's error state.
-
-However, when using Inertia, a `422` response is never returned by your server. Instead, as we saw in the example above, your routes / controllers will typically return a redirect response - much like a classic, full-page form submission.
-
-For a full discussion on handling and displaying [validation](/guide/validation.md) errors with Inertia, please consult the validation documentation.
-
-## Form helper
-
-Since working with forms is so common, Inertia includes a form helper designed to help reduce the amount of boilerplate code needed for handling typical form submissions.
-
-:::tabs key:frameworks
-== Vue 2
-
-```vue
-
-
-
-
-
-```
-
-== Vue 3
-
-```vue
-
-
-
-
-
-```
-
-== React
-
-```jsx
-import { useForm } from '@inertiajs/react'
-
-const { data, setData, post, processing, errors } = useForm({
- email: '',
- password: '',
- remember: false,
-})
-
-function submit(e) {
- e.preventDefault()
- post('/login')
-}
-
-return (
-
-)
-```
-
-== Svelte
-
-```svelte
-
-
-
-```
-
-:::
-
-To submit the form, you may use the `get`, `post`, `put`, `patch` and `delete` methods.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-form.submit(method, url, options)
-form.get(url, options)
-form.post(url, options)
-form.put(url, options)
-form.patch(url, options)
-form.delete(url, options)
-```
-
-== Vue 3
-
-```js
-form.submit(method, url, options)
-form.get(url, options)
-form.post(url, options)
-form.put(url, options)
-form.patch(url, options)
-form.delete(url, options)
-```
-
-== React
-
-```jsx
-const { submit, get, post, put, patch, delete: destroy } = useForm({ ... })
-
-submit(method, url, options)
-get(url, options)
-post(url, options)
-put(url, options)
-patch(url, options)
-destroy(url, options)
-```
-
-== Svelte
-
-```js
-$form.submit(method, url, options)
-$form.get(url, options)
-$form.post(url, options)
-$form.put(url, options)
-$form.patch(url, options)
-$form.delete(url, options)
-```
-
-:::
-
-The submit methods support all of the typical [visit options](/guide/manual-visits.md), such as `preserveState`, `preserveScroll`, and event callbacks, which can be helpful for performing tasks on successful form submissions. For example, you might use the `onSuccess` callback to reset inputs to their original state.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-form.post('/profile', {
- preserveScroll: true,
- onSuccess: () => form.reset('password'),
-})
-```
-
-== Vue 3
-
-```js
-form.post('/profile', {
- preserveScroll: true,
- onSuccess: () => form.reset('password'),
-})
-```
-
-== React
-
-```jsx
-const { post, reset } = useForm({ ... })
-
-post('/profile', {
-preserveScroll: true,
-onSuccess: () => reset('password'),
-})
-```
-
-== Svelte
-
-```js
-$form.post('/profile', {
- preserveScroll: true,
- onSuccess: () => $form.reset('password'),
-})
-```
-
-:::
-
-If you need to modify the form data before it's sent to the server, you can do so via the `transform()` method.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-form
- .transform((data) => ({
- ...data,
- remember: data.remember ? 'on' : '',
- }))
- .post('/login')
-```
-
-== Vue 3
-
-```js
-form
- .transform((data) => ({
- ...data,
- remember: data.remember ? 'on' : '',
- }))
- .post('/login')
-```
-
-== React
-
-```jsx
-const { transform } = useForm({ ... })
-
-transform((data) => ({
- ...data,
- remember: data.remember ? 'on' : '',
-}))
-```
-
-== Svelte
-
-```js
-$form
- .transform((data) => ({
- ...data,
- remember: data.remember ? 'on' : '',
- }))
- .post('/login')
-```
-
-:::
-
-You can use the `processing` property to track if a form is currently being submitted. This can be helpful for preventing double form submissions by disabling the submit button.
-
-:::tabs key:frameworks
-== Vue 2
-
-```vue
-
-```
-
-== Vue 3
-
-```vue
-
-```
-
-== React
-
-```jsx
-const { processing } = useForm({ ... })
-
-
-```
-
-== Svelte
-
-```svelte
-
-```
-
-:::
-
-If your form is uploading files, the current progress event is available via the `progress` property, allowing you to easily display the upload progress.
-
-:::tabs key:frameworks
-== Vue 2
-
-```vue
-
-```
-
-== Vue 3
-
-```vue
-
-```
-
-== React
-
-```jsx
-const { progress } = useForm({ ... })
-
-{progress && (
-
-)}
-```
-
-== Svelte
-
-```svelte
-{#if $form.progress}
-
-{/if}
-```
-
-:::
-
-If there are form validation errors, they are available via the `errors` property. When building Rails powered Inertia applications, form errors will automatically be populated when your application throws instances of `ActiveRecord::RecordInvalid`, such as when using `#save!`.
-
-:::tabs key:frameworks
-== Vue 2
-
-```vue
-
-{/if}
-```
-
-:::
-
-> [!NOTE]
-> For a more thorough discussion of form validation and errors, please consult the [validation documentation](/guide/validation.md).
-
-To determine if a form has any errors, you may use the `hasErrors` property. To clear form errors, use the `clearErrors()` method.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-// Clear all errors...
-form.clearErrors()
-
-// Clear errors for specific fields...
-form.clearErrors('field', 'anotherfield')
-```
-
-== Vue 3
-
-```js
-// Clear all errors...
-form.clearErrors()
-
-// Clear errors for specific fields...
-form.clearErrors('field', 'anotherfield')
-```
-
-== React
-
-```jsx
-const { clearErrors } = useForm({ ... })
-
-// Clear all errors...
-clearErrors()
-
-// Clear errors for specific fields...
-clearErrors('field', 'anotherfield')
-```
-
-== Svelte
-
-```js
-// Clear all errors...
-$form.clearErrors()
-
-// Clear errors for specific fields...
-$form.clearErrors('field', 'anotherfield')
-```
-
-:::
-
-If you're using a client-side input validation libraries or do client-side validation manually, you can set your own errors on the form using the `setErrors()` method.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-// Set a single error...
-form.setError('field', 'Your error message.')
-
-// Set multiple errors at once...
-form.setError({
- foo: 'Your error message for the foo field.',
- bar: 'Some other error for the bar field.',
-})
-```
-
-== Vue 3
-
-```js
-// Set a single error...
-form.setError('field', 'Your error message.')
-
-// Set multiple errors at once...
-form.setError({
- foo: 'Your error message for the foo field.',
- bar: 'Some other error for the bar field.',
-})
-```
-
-== React
-
-```jsx
-const { setError } = useForm({ ... })
-
-// Set a single error...
-setError('field', 'Your error message.');
-
-// Set multiple errors at once...
-setError({
- foo: 'Your error message for the foo field.',
- bar: 'Some other error for the bar field.'
-});
-```
-
-== Svelte
-
-```js
-// Set a single error
-$form.setError('field', 'Your error message.')
-
-// Set multiple errors at once
-$form.setError({
- foo: 'Your error message for the foo field.',
- bar: 'Some other error for the bar field.',
-})
-```
-
-:::
-
-> [!NOTE]
-> Unlike an actual form submission, the page's props remain unchanged when manually setting errors on a form instance.
-
-When a form has been successfully submitted, the `wasSuccessful` property will be `true`. In addition to this, forms have a `recentlySuccessful` property, which will be set to `true` for two seconds after a successful form submission. This property can be utilized to show temporary success messages.
-
-To reset the form's values back to their default values, you can use the `reset()` method.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-// Reset the form...
-form.reset()
-
-// Reset specific fields...
-form.reset('field', 'anotherfield')
-```
-
-== Vue 3
-
-```js
-// Reset the form...
-form.reset()
-
-// Reset specific fields...
-form.reset('field', 'anotherfield')
-```
-
-== React
-
-```jsx
-const { reset } = useForm({ ... })
-
-// Reset the form...
-reset()
-
-// Reset specific fields...
-reset('field', 'anotherfield')
-```
-
-== Svelte
-
-```js
-// Reset the form...
-$form.reset()
-
-// Reset specific fields...
-$form.reset('field', 'anotherfield')
-```
-
-:::
-
-If your form's default values become outdated, you can use the `defaults()` method to update them. Then, the form will be reset to the correct values the next time the `reset()` method is invoked.
-
-:::tabs key:frameworks
-== Vue 2
-
-```js
-// Set the form's current values as the new defaults...
-form.defaults()
-
-// Update the default value of a single field...
-form.defaults('email', 'updated-default@example.com')
-
-// Update the default value of multiple fields...
-form.defaults({
- name: 'Updated Example',
- email: 'updated-default@example.com',
-})
-```
-
-== Vue 3
-
-```js
-// Set the form's current values as the new defaults...
-form.defaults()
-
-// Update the default value of a single field...
-form.defaults('email', 'updated-default@example.com')
-
-// Update the default value of multiple fields...
-form.defaults({
- name: 'Updated Example',
- email: 'updated-default@example.com',
-})
-```
-
-== React
-
-```jsx
-const { setDefaults } = useForm({ ... })
-
-// Set the form's current values as the new defaults...
-setDefaults()
-
-// Update the default value of a single field...
-setDefaults('email', 'updated-default@example.com')
-
-// Update the default value of multiple fields...
-setDefaults({
- name: 'Updated Example',
- email: 'updated-default@example.com',
-})
-```
-
-== Svelte
-
-```js
-// Set the form's current values as the new defaults...
-$form.defaults()
-
-// Update the default value of a single field...
-$form.defaults('email', 'updated-default@example.com')
-
-// Change the default value of multiple fields...
-$form.defaults({
- name: 'Updated Example',
- email: 'updated-default@example.com',
-})
-```
-
-:::
-
-To determine if a form has any changes, you may use the `isDirty` property.
-
-:::tabs key:frameworks
-== Vue 2
-
-```vue
-
-{/if}
-```
-
-:::
-
-To cancel a form submission, use the `cancel()` method.
-
-:::tabs key:frameworks
-== Vue 2
-
-```vue
-form.cancel()
-```
-
-== Vue 3
-
-```vue
-form.cancel()
-```
-
-== React
-
-```jsx
-const { cancel } = useForm({ ... })
-
-cancel()
-```
-
-== Svelte
-
-```svelte
-$form.cancel()
-```
-
-:::
-
-To instruct Inertia to store a form's data and errors in [history state](/guide/remembering-state.md), you can provide a unique form key as the first argument when instantiating your form.
-
-:::tabs key:frameworks
-== Vue 2
-
-```vue
-import { useForm } from '@inertiajs/vue2'
-
-form: useForm('CreateUser', data)
-form: useForm(`EditUser:${this.user.id}`, data)
-```
-
-== Vue 3
-
-```vue
-import { useForm } from '@inertiajs/vue3'
-
-const form = useForm('CreateUser', data)
-const form = useForm(`EditUser:${user.id}`, data)
-```
-
-== React
-
-```jsx
-import { useForm } from '@inertiajs/react'
-
-const form = useForm('CreateUser', data)
-const form = useForm(`EditUser:${user.id}`, data)
-```
-
-== Svelte
-
-```svelte
-import { useForm } from '@inertiajs/svelte'
-
-const form = useForm('CreateUser', data)
-const form = useForm(`EditUser:${user.id}`, data)
-```
-
-:::
-
-## File uploads
-
-When making requests or form submissions that include files, Inertia will automatically convert the request data into a `FormData` object.
-
-For a more thorough discussion of file uploads, please consult the [file uploads documentation](/guide/file-uploads.md).
-
-## XHR / fetch submissions
-
-Using Inertia to submit forms works great for the vast majority of situations; however, in the event that you need more control over the form submission, you're free to make plain XHR or `fetch` requests instead using the library of your choice.
diff --git a/docs/guide/how-it-works.md b/docs/guide/how-it-works.md
deleted file mode 100644
index 2c71abe..0000000
--- a/docs/guide/how-it-works.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# How it works
-
-With Inertia you build applications just like you've always done with your server-side web framework of choice. You use your framework's existing functionality for routing, controllers, middleware, authentication, authorization, data fetching, and more.
-
-However, Inertia replaces your application's view layer. Instead of using server-side rendering via PHP or Ruby templates, the views returned by your application are JavaScript page components. This allows you to build your entire frontend using React, Vue, or Svelte, while still enjoying the productivity of Laravel or your preferred server-side framework.
-
-As you might expect, simply creating your frontend in JavaScript doesn't give you a single-page application experience. If you were to click a link, your browser would make a full page visit, which would then cause your client-side framework to reboot on the subsequent page load. This is where Inertia changes everything.
-
-At its core, Inertia is essentially a client-side routing library. It allows you to make page visits without forcing a full page reload. This is done using the `` component, a light-weight wrapper around a normal anchor link. When you click an Inertia link, Inertia intercepts the click and makes the visit via XHR instead. You can even make these visits programmatically in JavaScript using `router.visit()`.
-
-When Inertia makes an XHR visit, the server detects that it's an Inertia visit and, instead of returning a full HTML response, it returns a JSON response with the JavaScript page component name and data (props). Inertia then dynamically swaps out the previous page component with the new page component and updates the browser's history state.
-
-**The end result is a silky smooth single-page experience. 🎉**
-
-To learn more about the nitty-gritty, technical details of how Inertia works under the hood, check out [the protocol page](/guide/the-protocol.md).
diff --git a/docs/guide/index.md b/docs/guide/index.md
deleted file mode 100644
index 7d13c4d..0000000
--- a/docs/guide/index.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Introduction
-
-Welcome to the community documentation for [inertia_rails](https://github.com/inertiajs/inertia-rails) adapter for [Ruby on Rails](https://rubyonrails.org/) and [Inertia.js](https://inertiajs.com/).
-
-## Why community documentation?
-
-The [official documentation for Inertia.js](https://inertiajs.com) is great, but it's not Rails-specific anymore (see the [legacy docs](https://legacy.inertiajs.com)). This documentation aims to fill in the gaps and provide Rails-specific examples and explanations.
-
-## JavaScript apps the monolith way
-
-Inertia is a new approach to building classic server-driven web apps. We call it the modern monolith.
-
-Inertia allows you to create fully client-side rendered, single-page apps, without the complexity that comes with modern SPAs. It does this by leveraging existing server-side patterns that you already love.
-
-Inertia has no client-side routing, nor does it require an API. Simply build controllers and page views like you've always done!
-
-### Not a framework
-
-Inertia isn't a framework, nor is it a replacement for your existing server-side or client-side frameworks. Rather, it's designed to work with them. Think of Inertia as glue that connects the two. Inertia does this via adapters. We currently have three official client-side adapters (React, Vue, and Svelte) and two server-side adapters (Laravel and Rails).
-
-### Next steps
-
-Want to learn a bit more before diving in? Check out the [who is it for](/guide/who-is-it-for.md) and [how it works](/guide/how-it-works.md) pages. Or, if you're ready to get started, jump right into the [installation instructions](/guide/server-side-setup.md).
diff --git a/docs/guide/links.md b/docs/guide/links.md
deleted file mode 100644
index 91370b1..0000000
--- a/docs/guide/links.md
+++ /dev/null
@@ -1,525 +0,0 @@
-# Links
-
-To create links to other pages within an Inertia app, you will typically use the Inertia `` component. This component is a light wrapper around a standard anchor `` link that intercepts click events and prevents full page reloads. This is [how Inertia provides a single-page app experience](/guide/how-it-works.md) once your application has been loaded.
-
-## Creating links
-
-To create an Inertia link, use the Inertia `` component. Any attributes you provide to this component will be proxied to the underlying HTML tag.
-
-:::tabs key:frameworks
-
-== Vue 2
-
-```vue
-import { Link } from '@inertiajs/vue2'
-
-Home
-```
-
-== Vue 3
-
-```vue
-import { Link } from '@inertiajs/vue3'
-
-Home
-```
-
-== React
-
-```jsx
-import { Link } from '@inertiajs/react'
-
-Home
-```
-
-== Svelte
-
-```svelte
-import { inertia, Link } from '@inertiajs/svelte'
-
-Home
-
-Home
-```
-
-> [!TIP]
-> The `use:inertia` directive can be applied to any HTML element.
-
-:::
-
-By default, Inertia renders links as anchor `` elements. However, you can change the tag using the `as` prop.
-
-:::tabs key:frameworks
-== Vue 2
-
-```vue
-import { Link } from '@inertiajs/vue2'
-
-Logout
-
-// Renders as...
-
-```
-
-== Vue 3
-
-```vue
-import { Link } from '@inertiajs/vue3'
-
-Logout
-
-// Renders as...
-
-```
-
-== React
-
-```jsx
-import { Link } from '@inertiajs/react'
-
-Logout
-
-// Renders as...
-
-```
-
-== Svelte
-
-```svelte
-import { inertia } from '@inertiajs/svelte'
-
-
-
-// Renders as...
-
-```
-
-> [!NOTE]
-> Svelte does not support dynamic elements yet, but you can use the `inertia` directive to achieve the same results.
-
-:::
-
-> [!WARNING]
-> Creating `POST/PUT/PATCH/DELETE` anchor `` links is discouraged as it causes "Open Link in New Tab / Window" accessibility issues. Instead, consider using a more appropriate element, such as a `