diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 35f16c13..7fe0ef31 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -23,10 +23,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: '22' cache: 'npm' diff --git a/.github/workflows/generators.yml b/.github/workflows/generators.yml index 4ab4eabb..b88c4701 100644 --- a/.github/workflows/generators.yml +++ b/.github/workflows/generators.yml @@ -30,7 +30,7 @@ jobs: name: ${{ matrix.framework }} (TS:${{ matrix.typescript }}, TW:${{ matrix.tailwind }}, Inertia:${{ matrix.inertia_version }}) steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Ruby uses: ruby/setup-ruby@v1 @@ -42,7 +42,7 @@ jobs: run: bundle exec rspec --tag type:generator - name: Set up Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: ${{ matrix.node }} @@ -69,7 +69,7 @@ jobs: - name: Upload test artifacts if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: test-output-${{ matrix.framework }}-ts${{ matrix.typescript }}-tw${{ matrix.tailwind }}-v${{ matrix.inertia_version }} path: | diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index e885474c..9860f1a2 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -19,11 +19,11 @@ jobs: runs-on: ubuntu-latest name: Linter steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: "3.3" + ruby-version: "3.4" bundler: latest bundler-cache: true - name: Run RuboCop @@ -53,13 +53,13 @@ jobs: name: Test against Ruby ${{ matrix.ruby }} / Rails ${{ matrix.rails }} steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Setup System run: sudo apt-get install libsqlite3-dev - name: Set up Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22.x @@ -67,7 +67,7 @@ jobs: uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - rubygems: latest + rubygems: 'latest' bundler-cache: true env: RAILS_VERSION: ${{ matrix.rails }} diff --git a/Gemfile b/Gemfile index 8e9874e5..8048bfd4 100644 --- a/Gemfile +++ b/Gemfile @@ -8,7 +8,6 @@ gemspec version = ENV.fetch('RAILS_VERSION', '8.1') gem 'rails', "~> #{version}.0" -gem 'bundler', '~> 2.0' gem 'debug' gem 'generator_spec', '~> 0.10' gem 'rails-controller-testing' diff --git a/app/views/inertia.html.erb b/app/views/inertia.html.erb index e52113b8..8eeec0fc 100644 --- a/app/views/inertia.html.erb +++ b/app/views/inertia.html.erb @@ -1 +1 @@ -
+<%= inertia_root(page: page) %> diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 7ff43e12..ffc66c9e 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -136,6 +136,7 @@ export default defineConfig({ { text: 'Prefetching', link: '/guide/prefetching' }, { text: 'Load when visible', link: '/guide/load-when-visible' }, { text: 'Merging props', link: '/guide/merging-props' }, + { text: 'Once props', link: '/guide/once-props' }, { text: 'Infinite scroll', link: '/guide/infinite-scroll' }, { text: 'Remembering state', link: '/guide/remembering-state' }, ], diff --git a/docs/cookbook/handling-validation-error-types.md b/docs/cookbook/handling-validation-error-types.md index 475153fc..d7bc4843 100644 --- a/docs/cookbook/handling-validation-error-types.md +++ b/docs/cookbook/handling-validation-error-types.md @@ -26,8 +26,10 @@ import type { InertiaFormProps as OriginalProps } from '@inertiajs/vue3' type FormDataType = Record declare module '@inertiajs/vue3' { - interface InertiaFormProps - extends Omit, 'errors' | 'setError'> { + interface InertiaFormProps extends Omit< + OriginalProps, + 'errors' | 'setError' + > { errors: Partial, string[]>> setError(field: FormDataKeys, value: string[]): this @@ -60,8 +62,10 @@ import type { InertiaFormProps as OriginalProps } from '@inertiajs/react' type FormDataType = Record declare module '@inertiajs/react' { - interface InertiaFormProps - extends Omit, 'errors' | 'setError'> { + interface InertiaFormProps extends Omit< + OriginalProps, + 'errors' | 'setError' + > { errors: Partial, string[]>> setError(field: FormDataKeys, value: string[]): void @@ -92,8 +96,10 @@ import type { Writable } from 'svelte/store' type FormDataType = Record declare module '@inertiajs/svelte' { - interface InertiaFormProps - extends Omit, 'errors' | 'setError'> { + interface InertiaFormProps extends Omit< + OriginalProps, + 'errors' | 'setError' + > { errors: Partial, string[]>> setError(field: FormDataKeys, value: string[]): this diff --git a/docs/guide/client-side-setup.md b/docs/guide/client-side-setup.md index 01732666..98566a7e 100644 --- a/docs/guide/client-side-setup.md +++ b/docs/guide/client-side-setup.md @@ -292,3 +292,26 @@ createInertiaApp({ // ... }) ``` + +> [!NOTE] +> Make sure the [`root_dom_id`](/guide/configuration#root_dom_id) configuration option matches the `id` property in your client-side setup. + +## Script Element for Page Data + +By default, Inertia stores the initial page data in a `data-page` attribute on the root element. You may configure Inertia to use a ` +
+``` + +> [!NOTE] +> When using this option make sure your client-side Inertia setup is configured to read the page data from the ` +
+``` + +See the [`use_script_element_for_initial_page`](/guide/configuration#use_script_element_for_initial_page) configuration option to enable this behavior. + While the initial response is HTML, Inertia does not server-side render the JavaScript page components. For information on server-side rendering, see the [SSR documentation](/guide/server-side-rendering). ## Inertia responses @@ -97,6 +124,7 @@ The following headers are automatically sent by Inertia when making requests. Yo 10. `Cache-Control`: Set to `no-cache` for reload requests to prevent serving stale content. 11. `X-Inertia-Error-Bag`: Specifies which error bag to use for [validation errors](/guide/validation). 12. `X-Inertia-Infinite-Scroll-Merge-Intent`: Indicates whether the requested data should be appended or prepended when using [Infinite scroll](/guide/infinite-scroll). +13. `X-Inertia-Except-Once-Props`: Comma-separated list of non-expired [once prop](/guide/once-props) keys already loaded on the client. The server will skip resolving these props unless explicitly requested via a partial reload or force refreshed server-side. ## Response headers @@ -122,6 +150,7 @@ Inertia shares data between the server and client via a page object. This object - `matchPropsOn`: Array of prop keys to use for [matching when merging props](/guide/merging-props#matching-items). - `scrollProps`: Configuration for [infinite scroll](/guide/infinite-scroll) prop merging behavior. - `deferredProps`: Configuration for client-side [lazy loading of props](/guide/deferred-props). +- `onceProps`: Configuration for [once props](/guide/once-props) that should only be resolved once and reused on subsequent pages. Each entry maps a key to an object containing the `prop` name and optional `expiresAt` timestamp (in milliseconds). On standard full page visits, the page object is JSON encoded into the `data-page` attribute in the root `
`. On Inertia visits (as indicated by the presence of the `X-Inertia` header), the page object is returned as the JSON payload. @@ -252,6 +281,78 @@ When using [Infinite scroll](/guide/infinite-scroll), the page object includes a } ``` +### Page Object with Once Props + +When using [once props](/guide/once-props), the page object includes an `onceProps` configuration. Each entry maps a key to the prop name and an optional expiration timestamp. + +```json +{ + "component": "Billing/Plans", + "props": { + "errors": {}, + "plans": [ + { + "id": 1, + "name": "Basic" + }, + { + "id": 2, + "name": "Pro" + } + ] + }, + "url": "/billing/plans", + "version": "6b16b94d7c51cbe5b1fa42aac98241d5", + "clearHistory": false, + "encryptHistory": false, + "onceProps": { + "plans": { + "prop": "plans", + "expiresAt": null + } + } +} +``` + +When navigating to a subsequent page that includes the same once prop, the client sends the loaded keys in the `X-Inertia-Except-Once-Props` header. The server skips resolving these props and excludes them from the response. The client reuses the previously loaded values. + +```http +REQUEST +GET: https://example.com/billing/upgrade +Accept: text/html, application/xhtml+xml +X-Requested-With: XMLHttpRequest +X-Inertia: true +X-Inertia-Version: 6b16b94d7c51cbe5b1fa42aac98241d5 +X-Inertia-Except-Once-Props: plans + +RESPONSE +HTTP/1.1 200 OK +Content-Type: application/json + +{ + "component": "Billing/Upgrade", + "props": { + "errors": {}, + "currentPlan": { + "id": 1, + "name": "Basic" + } + }, + "url": "/billing/upgrade", + "version": "6b16b94d7c51cbe5b1fa42aac98241d5", + "clearHistory": false, + "encryptHistory": false, + "onceProps": { + "plans": { + "prop": "plans", + "expiresAt": null + } + } +} +``` + +Note that `plans` is included in `onceProps` but not in `props` since it was already loaded on the client. The `onceProps` key identifies the once prop across pages, while `prop` specifies the actual prop name. These may differ when using [custom keys](/guide/once-props#custom-keys). + ## Asset versioning One common challenge with single-page apps is refreshing site assets when they've been changed. Inertia makes this easy by optionally tracking the current version of the site's assets. In the event that an asset changes, Inertia will automatically make a full-page visit instead of an XHR visit. diff --git a/docs/package-lock.json b/docs/package-lock.json index e587c6ec..a6198dfa 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -21,16 +21,16 @@ } }, "node_modules/@algolia/abtesting": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.11.0.tgz", - "integrity": "sha512-a7oQ8dwiyoyVmzLY0FcuBqyqcNSq78qlcOtHmNBumRlHCSnXDcuoYGBGPN1F6n8JoGhviDDsIaF/oQrzTzs6Lg==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.12.0.tgz", + "integrity": "sha512-EfW0bfxjPs+C7ANkJDw2TATntfBKsFiy7APh+KO0pQ8A6HYa5I0NjFuCGCXWfzzzLXNZta3QUl3n5Kmm6aJo9Q==", "dev": true, "license": "MIT", "dependencies": { - "@algolia/client-common": "5.45.0", - "@algolia/requester-browser-xhr": "5.45.0", - "@algolia/requester-fetch": "5.45.0", - "@algolia/requester-node-http": "5.45.0" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" @@ -86,41 +86,41 @@ } }, "node_modules/@algolia/client-abtesting": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.45.0.tgz", - "integrity": "sha512-WTW0VZA8xHMbzuQD5b3f41ovKZ0MNTIXkWfm0F2PU+XGcLxmxX15UqODzF2sWab0vSbi3URM1xLhJx+bXbd1eQ==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.46.0.tgz", + "integrity": "sha512-eG5xV8rujK4ZIHXrRshvv9O13NmU/k42Rnd3w43iKH5RaQ2zWuZO6Q7XjaoJjAFVCsJWqRbXzbYyPGrbF3wGNg==", "dev": true, "license": "MIT", "dependencies": { - "@algolia/client-common": "5.45.0", - "@algolia/requester-browser-xhr": "5.45.0", - "@algolia/requester-fetch": "5.45.0", - "@algolia/requester-node-http": "5.45.0" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-analytics": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.45.0.tgz", - "integrity": "sha512-I3g7VtvG/QJOH3tQO7E7zWTwBfK/nIQXShFLR8RvPgWburZ626JNj332M3wHCYcaAMivN9WJG66S2JNXhm6+Xg==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.46.0.tgz", + "integrity": "sha512-AYh2uL8IUW9eZrbbT+wZElyb7QkkeV3US2NEKY7doqMlyPWE8lErNfkVN1NvZdVcY4/SVic5GDbeDz2ft8YIiQ==", "dev": true, "license": "MIT", "dependencies": { - "@algolia/client-common": "5.45.0", - "@algolia/requester-browser-xhr": "5.45.0", - "@algolia/requester-fetch": "5.45.0", - "@algolia/requester-node-http": "5.45.0" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-common": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.45.0.tgz", - "integrity": "sha512-/nTqm1tLiPtbUr+8kHKyFiCOfhRfgC+JxLvOCq471gFZZOlsh6VtFRiKI60/zGmHTojFC6B0mD80PB7KeK94og==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.46.0.tgz", + "integrity": "sha512-0emZTaYOeI9WzJi0TcNd2k3SxiN6DZfdWc2x2gHt855Jl9jPUOzfVTL6gTvCCrOlT4McvpDGg5nGO+9doEjjig==", "dev": true, "license": "MIT", "engines": { @@ -128,152 +128,152 @@ } }, "node_modules/@algolia/client-insights": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.45.0.tgz", - "integrity": "sha512-suQTx/1bRL1g/K2hRtbK3ANmbzaZCi13487sxxmqok+alBDKKw0/TI73ZiHjjFXM2NV52inwwcmW4fUR45206Q==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.46.0.tgz", + "integrity": "sha512-wrBJ8fE+M0TDG1As4DDmwPn2TXajrvmvAN72Qwpuv8e2JOKNohF7+JxBoF70ZLlvP1A1EiH8DBu+JpfhBbNphQ==", "dev": true, "license": "MIT", "dependencies": { - "@algolia/client-common": "5.45.0", - "@algolia/requester-browser-xhr": "5.45.0", - "@algolia/requester-fetch": "5.45.0", - "@algolia/requester-node-http": "5.45.0" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-personalization": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.45.0.tgz", - "integrity": "sha512-CId/dbjpzI3eoUhPU6rt/z4GrRsDesqFISEMOwrqWNSrf4FJhiUIzN42Ac+Gzg69uC0RnzRYy60K1y4Na5VSMw==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.46.0.tgz", + "integrity": "sha512-LnkeX4p0ENt0DoftDJJDzQQJig/sFQmD1eQifl/iSjhUOGUIKC/7VTeXRcKtQB78naS8njUAwpzFvxy1CDDXDQ==", "dev": true, "license": "MIT", "dependencies": { - "@algolia/client-common": "5.45.0", - "@algolia/requester-browser-xhr": "5.45.0", - "@algolia/requester-fetch": "5.45.0", - "@algolia/requester-node-http": "5.45.0" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-query-suggestions": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.45.0.tgz", - "integrity": "sha512-tjbBKfA8fjAiFtvl9g/MpIPiD6pf3fj7rirVfh1eMIUi8ybHP4ovDzIaE216vHuRXoePQVCkMd2CokKvYq1CLw==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.46.0.tgz", + "integrity": "sha512-aF9tc4ex/smypXw+W3lBPB1jjKoaGHpZezTqofvDOI/oK1dR2sdTpFpK2Ru+7IRzYgwtRqHF3znmTlyoNs9dpA==", "dev": true, "license": "MIT", "dependencies": { - "@algolia/client-common": "5.45.0", - "@algolia/requester-browser-xhr": "5.45.0", - "@algolia/requester-fetch": "5.45.0", - "@algolia/requester-node-http": "5.45.0" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/client-search": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.45.0.tgz", - "integrity": "sha512-nxuCid+Nszs4xqwIMDw11pRJPes2c+Th1yup/+LtpjFH8QWXkr3SirNYSD3OXAeM060HgWWPLA8/Fxk+vwxQOA==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.46.0.tgz", + "integrity": "sha512-22SHEEVNjZfFWkFks3P6HilkR3rS7a6GjnCIqR22Zz4HNxdfT0FG+RE7efTcFVfLUkTTMQQybvaUcwMrHXYa7Q==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@algolia/client-common": "5.45.0", - "@algolia/requester-browser-xhr": "5.45.0", - "@algolia/requester-fetch": "5.45.0", - "@algolia/requester-node-http": "5.45.0" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/ingestion": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.45.0.tgz", - "integrity": "sha512-t+1doBzhkQTeOOjLHMlm4slmXBhvgtEGQhOmNpMPTnIgWOyZyESWdm+XD984qM4Ej1i9FRh8VttOGrdGnAjAng==", + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.46.0.tgz", + "integrity": "sha512-2LT0/Z+/sFwEpZLH6V17WSZ81JX2uPjgvv5eNlxgU7rPyup4NXXfuMbtCJ+6uc4RO/LQpEJd3Li59ke3wtyAsA==", "dev": true, "license": "MIT", "dependencies": { - "@algolia/client-common": "5.45.0", - "@algolia/requester-browser-xhr": "5.45.0", - "@algolia/requester-fetch": "5.45.0", - "@algolia/requester-node-http": "5.45.0" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/monitoring": { - "version": "1.45.0", - "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.45.0.tgz", - "integrity": "sha512-IaX3ZX1A/0wlgWZue+1BNWlq5xtJgsRo7uUk/aSiYD7lPbJ7dFuZ+yTLFLKgbl4O0QcyHTj1/mSBj9ryF1Lizg==", + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.46.0.tgz", + "integrity": "sha512-uivZ9wSWZ8mz2ZU0dgDvQwvVZV8XBv6lYBXf8UtkQF3u7WeTqBPeU8ZoeTyLpf0jAXCYOvc1mAVmK0xPLuEwOQ==", "dev": true, "license": "MIT", "dependencies": { - "@algolia/client-common": "5.45.0", - "@algolia/requester-browser-xhr": "5.45.0", - "@algolia/requester-fetch": "5.45.0", - "@algolia/requester-node-http": "5.45.0" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/recommend": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.45.0.tgz", - "integrity": "sha512-1jeMLoOhkgezCCPsOqkScwYzAAc1Jr5T2hisZl0s32D94ZV7d1OHozBukgOjf8Dw+6Hgi6j52jlAdUWTtkX9Mg==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.46.0.tgz", + "integrity": "sha512-O2BB8DuySuddgOAbhyH4jsGbL+KyDGpzJRtkDZkv091OMomqIA78emhhMhX9d/nIRrzS1wNLWB/ix7Hb2eV5rg==", "dev": true, "license": "MIT", "dependencies": { - "@algolia/client-common": "5.45.0", - "@algolia/requester-browser-xhr": "5.45.0", - "@algolia/requester-fetch": "5.45.0", - "@algolia/requester-node-http": "5.45.0" + "@algolia/client-common": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-browser-xhr": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.45.0.tgz", - "integrity": "sha512-46FIoUkQ9N7wq4/YkHS5/W9Yjm4Ab+q5kfbahdyMpkBPJ7IBlwuNEGnWUZIQ6JfUZuJVojRujPRHMihX4awUMg==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.46.0.tgz", + "integrity": "sha512-eW6xyHCyYrJD0Kjk9Mz33gQ40LfWiEA51JJTVfJy3yeoRSw/NXhAL81Pljpa0qslTs6+LO/5DYPZddct6HvISQ==", "dev": true, "license": "MIT", "dependencies": { - "@algolia/client-common": "5.45.0" + "@algolia/client-common": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-fetch": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.45.0.tgz", - "integrity": "sha512-XFTSAtCwy4HdBhSReN2rhSyH/nZOM3q3qe5ERG2FLbYId62heIlJBGVyAPRbltRwNlotlydbvSJ+SQ0ruWC2cw==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.46.0.tgz", + "integrity": "sha512-Vn2+TukMGHy4PIxmdvP667tN/MhS7MPT8EEvEhS6JyFLPx3weLcxSa1F9gVvrfHWCUJhLWoMVJVB2PT8YfRGcw==", "dev": true, "license": "MIT", "dependencies": { - "@algolia/client-common": "5.45.0" + "@algolia/client-common": "5.46.0" }, "engines": { "node": ">= 14.0.0" } }, "node_modules/@algolia/requester-node-http": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.45.0.tgz", - "integrity": "sha512-8mTg6lHx5i44raCU52APsu0EqMsdm4+7Hch/e4ZsYZw0hzwkuaMFh826ngnkYf9XOl58nHoou63aZ874m8AbpQ==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.46.0.tgz", + "integrity": "sha512-xaqXyna5yBZ+r1SJ9my/DM6vfTqJg9FJgVydRJ0lnO+D5NhqGW/qaRG/iBGKr/d4fho34el6WakV7BqJvrl/HQ==", "dev": true, "license": "MIT", "dependencies": { - "@algolia/client-common": "5.45.0" + "@algolia/client-common": "5.46.0" }, "engines": { "node": ">= 14.0.0" @@ -782,9 +782,9 @@ } }, "node_modules/@iconify-json/simple-icons": { - "version": "1.2.60", - "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.60.tgz", - "integrity": "sha512-KlwLBKCdMCqfySdkAA+jehdUx6VSjnj6lvzQKus7HjkPSQ6QP58d6xiptkIp0jd/Hw3PW2++nRuGvCvSYaF0Mg==", + "version": "1.2.62", + "resolved": "https://registry.npmjs.org/@iconify-json/simple-icons/-/simple-icons-1.2.62.tgz", + "integrity": "sha512-GpWQ294d4lraB3D2eBSSMROh1x9uKgpmyereLlGzVQjGZ7lbeFzby2ywXxyp4vEODmTDyf1/4WcOYs/yH4rJ5Q==", "dev": true, "license": "CC0-1.0", "dependencies": { @@ -1303,9 +1303,9 @@ "license": "MIT" }, "node_modules/@sveltejs/acorn-typescript": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.7.tgz", - "integrity": "sha512-znp1A/Y1Jj4l/Zy7PX5DZKBE0ZNY+5QBngiE21NJkfSTyzzC5iKNWOtwFXKtIrn7MXEFBck4jD95iBNkGjK92Q==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.8.tgz", + "integrity": "sha512-esgN+54+q0NjB0Y/4BomT9samII7jGwNy/2a3wNZbT2A2RpmXsXwUt24LvLhx6jUq2gVk4cWEvcRO6MFQbOfNA==", "dev": true, "license": "MIT", "peerDependencies": { @@ -1417,30 +1417,30 @@ } }, "node_modules/@volar/language-core": { - "version": "2.4.23", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.23.tgz", - "integrity": "sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==", + "version": "2.4.26", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.26.tgz", + "integrity": "sha512-hH0SMitMxnB43OZpyF1IFPS9bgb2I3bpCh76m2WEK7BE0A0EzpYsRp0CCH2xNKshr7kacU5TQBLYn4zj7CG60A==", "dev": true, "license": "MIT", "dependencies": { - "@volar/source-map": "2.4.23" + "@volar/source-map": "2.4.26" } }, "node_modules/@volar/source-map": { - "version": "2.4.23", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.23.tgz", - "integrity": "sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==", + "version": "2.4.26", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.26.tgz", + "integrity": "sha512-JJw0Tt/kSFsIRmgTQF4JSt81AUSI1aEye5Zl65EeZ8H35JHnTvFGmpDOBn5iOxd48fyGE+ZvZBp5FcgAy/1Qhw==", "dev": true, "license": "MIT" }, "node_modules/@volar/typescript": { - "version": "2.4.23", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.23.tgz", - "integrity": "sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag==", + "version": "2.4.26", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.26.tgz", + "integrity": "sha512-N87ecLD48Sp6zV9zID/5yuS1+5foj0DfuYGdQ6KHj/IbKvyKv1zNX6VCmnKYwtmHadEO6mFc2EKISiu3RDPAvA==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.23", + "@volar/language-core": "2.4.26", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } @@ -1549,13 +1549,13 @@ } }, "node_modules/@vue/language-core": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.1.5.tgz", - "integrity": "sha512-FMcqyzWN+sYBeqRMWPGT2QY0mUasZMVIuHvmb5NT3eeqPrbHBYtCP8JWEUCDCgM+Zr62uuWY/qoeBrPrzfa78w==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-3.1.8.tgz", + "integrity": "sha512-PfwAW7BLopqaJbneChNL6cUOTL3GL+0l8paYP5shhgY5toBNidWnMXWM+qDwL7MC9+zDtzCF2enT8r6VPu64iw==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.23", + "@volar/language-core": "2.4.26", "@vue/compiler-dom": "^3.5.0", "@vue/shared": "^3.5.0", "alien-signals": "^3.0.0", @@ -1748,27 +1748,27 @@ } }, "node_modules/algoliasearch": { - "version": "5.45.0", - "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.45.0.tgz", - "integrity": "sha512-wrj4FGr14heLOYkBKV3Fbq5ZBGuIFeDJkTilYq/G+hH1CSlQBtYvG2X1j67flwv0fUeQJwnWxxRIunSemAZirA==", + "version": "5.46.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.46.0.tgz", + "integrity": "sha512-7ML6fa2K93FIfifG3GMWhDEwT5qQzPTmoHKCTvhzGEwdbQ4n0yYUWZlLYT75WllTGJCJtNUI0C1ybN4BCegqvg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@algolia/abtesting": "1.11.0", - "@algolia/client-abtesting": "5.45.0", - "@algolia/client-analytics": "5.45.0", - "@algolia/client-common": "5.45.0", - "@algolia/client-insights": "5.45.0", - "@algolia/client-personalization": "5.45.0", - "@algolia/client-query-suggestions": "5.45.0", - "@algolia/client-search": "5.45.0", - "@algolia/ingestion": "1.45.0", - "@algolia/monitoring": "1.45.0", - "@algolia/recommend": "5.45.0", - "@algolia/requester-browser-xhr": "5.45.0", - "@algolia/requester-fetch": "5.45.0", - "@algolia/requester-node-http": "5.45.0" + "@algolia/abtesting": "1.12.0", + "@algolia/client-abtesting": "5.46.0", + "@algolia/client-analytics": "5.46.0", + "@algolia/client-common": "5.46.0", + "@algolia/client-insights": "5.46.0", + "@algolia/client-personalization": "5.46.0", + "@algolia/client-query-suggestions": "5.46.0", + "@algolia/client-search": "5.46.0", + "@algolia/ingestion": "1.46.0", + "@algolia/monitoring": "1.46.0", + "@algolia/recommend": "5.46.0", + "@algolia/requester-browser-xhr": "5.46.0", + "@algolia/requester-fetch": "5.46.0", + "@algolia/requester-node-http": "5.46.0" }, "engines": { "node": ">= 14.0.0" @@ -1863,9 +1863,9 @@ } }, "node_modules/birpc": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.8.0.tgz", - "integrity": "sha512-Bz2a4qD/5GRhiHSwj30c/8kC8QGj12nNDwz3D4ErQ4Xhy35dsSDvF+RA/tWpjyU0pdGtSDiEk6B5fBGE1qNVhw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz", + "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==", "dev": true, "license": "MIT", "funding": { @@ -2163,9 +2163,9 @@ } }, "node_modules/devalue": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.5.0.tgz", - "integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==", + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.0.tgz", + "integrity": "sha512-BaD1s81TFFqbD6Uknni42TrolvEWA1Ih5L+OiHWmi4OYMJVwAYPGtha61I9KxTf52OvVHozHyjPu8zljqdF3uA==", "dev": true, "license": "MIT" }, @@ -2308,9 +2308,9 @@ } }, "node_modules/esrap": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.0.tgz", - "integrity": "sha512-WBmtxe7R9C5mvL4n2le8nMUe4mD5V9oiK2vJpQ9I3y20ENPUomPcphBXE8D1x/Bm84oN1V+lOfgXxtqmxTp3Xg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.2.1.tgz", + "integrity": "sha512-GiYWG34AN/4CUyaWAgunGt0Rxvr1PTMlGC0vvEov/uOQYWne2bpN03Um+k8jT+q3op33mKouP2zeJ6OlM+qeUg==", "dev": true, "license": "MIT", "dependencies": { @@ -3769,9 +3769,9 @@ } }, "node_modules/preact": { - "version": "10.27.2", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.27.2.tgz", - "integrity": "sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==", + "version": "10.28.0", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.0.tgz", + "integrity": "sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA==", "dev": true, "license": "MIT", "funding": { @@ -3780,9 +3780,9 @@ } }, "node_modules/prettier": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", - "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz", + "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", "dev": true, "license": "MIT", "peer": true, @@ -3827,9 +3827,9 @@ } }, "node_modules/prettier-plugin-tailwindcss": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.7.1.tgz", - "integrity": "sha512-Bzv1LZcuiR1Sk02iJTS1QzlFNp/o5l2p3xkopwOrbPmtMeh3fK9rVW5M3neBQzHq+kGKj/4LGQMTNcTH4NGPtQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.7.2.tgz", + "integrity": "sha512-LkphyK3Fw+q2HdMOoiEHWf93fNtYJwfamoKPl7UwtjFQdei/iIBoX11G6j706FzN3ymX9mPVi97qIY8328vdnA==", "dev": true, "license": "MIT", "engines": { @@ -3966,9 +3966,9 @@ } }, "node_modules/regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/regex/-/regex-6.0.1.tgz", - "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", + "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", "dev": true, "license": "MIT", "dependencies": { @@ -4365,9 +4365,9 @@ } }, "node_modules/superjson": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.5.tgz", - "integrity": "sha512-zWPTX96LVsA/eVYnqOM2+ofcdPqdS1dAF1LN4TS2/MWuUpfitd9ctTa87wt4xrYnZnkLtS69xpBdSxVBP5Rm6w==", + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.6.tgz", + "integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==", "dev": true, "license": "MIT", "dependencies": { @@ -4378,9 +4378,9 @@ } }, "node_modules/svelte": { - "version": "5.44.1", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.44.1.tgz", - "integrity": "sha512-8VnkRXpa6tJ9IqiwKvzZBNnBy9tZg0N63duDz0EJqiozsmBEAZfHiZzWWWAneIN+cAWkK1JkafW1xIbC4YrdBA==", + "version": "5.45.8", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.45.8.tgz", + "integrity": "sha512-1Jh7FwVh/2Uxg0T7SeE1qFKMhwYH45b2v53bcZpW7qHa6O8iU1ByEj56PF0IQ6dU4HE5gRkic6h+vx+tclHeiw==", "dev": true, "license": "MIT", "peer": true, @@ -4395,7 +4395,7 @@ "clsx": "^2.1.1", "devalue": "^5.5.0", "esm-env": "^1.2.1", - "esrap": "^2.1.0", + "esrap": "^2.2.1", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", @@ -4816,15 +4816,15 @@ } }, "node_modules/vue-tsc": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.1.5.tgz", - "integrity": "sha512-L/G9IUjOWhBU0yun89rv8fKqmKC+T0HfhrFjlIml71WpfBv9eb4E9Bev8FMbyueBIU9vxQqbd+oOsVcDa5amGw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-3.1.8.tgz", + "integrity": "sha512-deKgwx6exIHeZwF601P1ktZKNF0bepaSN4jBU3AsbldPx9gylUc1JDxYppl82yxgkAgaz0Y0LCLOi+cXe9HMYA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@volar/typescript": "2.4.23", - "@vue/language-core": "3.1.5" + "@volar/typescript": "2.4.26", + "@vue/language-core": "3.1.8" }, "bin": { "vue-tsc": "bin/vue-tsc.js" diff --git a/lib/generators/inertia/install/templates/initializer.rb b/lib/generators/inertia/install/templates/initializer.rb index 83ef4b25..c8430fd1 100644 --- a/lib/generators/inertia/install/templates/initializer.rb +++ b/lib/generators/inertia/install/templates/initializer.rb @@ -4,4 +4,5 @@ config.version = ViteRuby.digest config.encrypt_history = true config.always_include_errors_hash = true + config.use_script_element_for_initial_page = true end diff --git a/lib/generators/inertia/install/templates/react/inertia.jsx b/lib/generators/inertia/install/templates/react/inertia.jsx index ef676f37..40e0c804 100644 --- a/lib/generators/inertia/install/templates/react/inertia.jsx +++ b/lib/generators/inertia/install/templates/react/inertia.jsx @@ -44,6 +44,7 @@ createInertiaApp({ forceIndicesArrayFormatInFormData: false, }, future: { + useScriptElementForInitialPage: true, useDataInertiaHeadAttribute: true, useDialogForErrorModal: true, preserveEqualProps: true, diff --git a/lib/generators/inertia/install/templates/react/inertia.tsx b/lib/generators/inertia/install/templates/react/inertia.tsx index 7bd3c6ae..da8b75c8 100644 --- a/lib/generators/inertia/install/templates/react/inertia.tsx +++ b/lib/generators/inertia/install/templates/react/inertia.tsx @@ -44,6 +44,7 @@ void createInertiaApp({ forceIndicesArrayFormatInFormData: false, }, future: { + useScriptElementForInitialPage: true, useDataInertiaHeadAttribute: true, useDialogForErrorModal: true, preserveEqualProps: true, diff --git a/lib/generators/inertia/install/templates/svelte/inertia.ts b/lib/generators/inertia/install/templates/svelte/inertia.ts index 11ed3de6..58d19f92 100644 --- a/lib/generators/inertia/install/templates/svelte/inertia.ts +++ b/lib/generators/inertia/install/templates/svelte/inertia.ts @@ -42,6 +42,7 @@ createInertiaApp({ forceIndicesArrayFormatInFormData: false, }, future: { + useScriptElementForInitialPage: true, useDataInertiaHeadAttribute: true, useDialogForErrorModal: true, preserveEqualProps: true, diff --git a/lib/generators/inertia/install/templates/vue/inertia.ts b/lib/generators/inertia/install/templates/vue/inertia.ts index d4073351..e2968cf0 100644 --- a/lib/generators/inertia/install/templates/vue/inertia.ts +++ b/lib/generators/inertia/install/templates/vue/inertia.ts @@ -41,6 +41,7 @@ createInertiaApp({ forceIndicesArrayFormatInFormData: false, }, future: { + useScriptElementForInitialPage: true, useDataInertiaHeadAttribute: true, useDialogForErrorModal: true, preserveEqualProps: true, diff --git a/lib/inertia_rails/base_prop.rb b/lib/inertia_rails/base_prop.rb index 1ee723b8..f8b75cae 100644 --- a/lib/inertia_rails/base_prop.rb +++ b/lib/inertia_rails/base_prop.rb @@ -3,7 +3,7 @@ module InertiaRails # Base class for all props. class BaseProp - def initialize(&block) + def initialize(**, &block) @block = block end diff --git a/lib/inertia_rails/configuration.rb b/lib/inertia_rails/configuration.rb index 482802c3..e8603b9d 100644 --- a/lib/inertia_rails/configuration.rb +++ b/lib/inertia_rails/configuration.rb @@ -34,6 +34,12 @@ class Configuration # Whether to include empty `errors` hash to the props when no errors are present. always_include_errors_hash: nil, + + # Whether to use `') + end + + it 'renders div without data-page attribute' do + expect(response.body).to include('
') + end + end + + context 'when true with custom root_dom_id' do + before do + InertiaRails.configure do |c| + c.use_script_element_for_initial_page = true + c.root_dom_id = 'inertia-app' + end + get component_path + end + + it 'renders script element with custom data-page attribute' do + expect(response.body).to include('