From fc458214980ed9a7f1a5cf25e230be3f465fc9b9 Mon Sep 17 00:00:00 2001 From: Paulo Carvalho Date: Sat, 25 Apr 2026 12:23:04 +0100 Subject: [PATCH 1/4] Add marko inertia svelte package --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 + .github/ISSUE_TEMPLATE/feature_request.yml | 1 + composer.json | 6 ++ packages/inertia-svelte/.gitattributes | 5 ++ packages/inertia-svelte/LICENSE | 20 +++++++ packages/inertia-svelte/README.md | 60 +++++++++++++++++++ packages/inertia-svelte/composer.json | 28 +++++++++ .../inertia-svelte/config/inertia-svelte.php | 14 +++++ packages/inertia-svelte/module.php | 10 ++++ .../tests/InertiaSvelteTest.php | 19 ++++++ 10 files changed, 164 insertions(+) create mode 100644 packages/inertia-svelte/.gitattributes create mode 100644 packages/inertia-svelte/LICENSE create mode 100644 packages/inertia-svelte/README.md create mode 100644 packages/inertia-svelte/composer.json create mode 100644 packages/inertia-svelte/config/inertia-svelte.php create mode 100644 packages/inertia-svelte/module.php create mode 100644 packages/inertia-svelte/tests/InertiaSvelteTest.php diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 8d25f027..0d891c92 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -83,6 +83,7 @@ body: - http-guzzle - inertia - inertia-react + - inertia-svelte - inertia-vue - layout - log diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index 1e090a3e..3d16ab77 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -71,6 +71,7 @@ body: - http-guzzle - inertia - inertia-react + - inertia-svelte - inertia-vue - layout - log diff --git a/composer.json b/composer.json index bc00825c..180e12e2 100644 --- a/composer.json +++ b/composer.json @@ -148,6 +148,10 @@ "type": "path", "url": "packages/inertia-react" }, + { + "type": "path", + "url": "packages/inertia-svelte" + }, { "type": "path", "url": "packages/inertia-vue" @@ -350,6 +354,7 @@ "marko/health": "self.version", "marko/inertia": "self.version", "marko/inertia-react": "self.version", + "marko/inertia-svelte": "self.version", "marko/inertia-vue": "self.version", "marko/http": "self.version", "marko/layout": "self.version", @@ -458,6 +463,7 @@ "Marko\\Health\\Tests\\": "packages/health/tests/", "Marko\\Inertia\\Tests\\": "packages/inertia/tests/", "Marko\\Inertia\\React\\Tests\\": "packages/inertia-react/tests/", + "Marko\\InertiaSvelte\\Tests\\": "packages/inertia-svelte/tests/", "Marko\\Inertia\\Vue\\Tests\\": "packages/inertia-vue/tests/", "Marko\\Http\\Tests\\": "packages/http/tests/", "Marko\\Http\\Guzzle\\Tests\\": "packages/http-guzzle/tests/", diff --git a/packages/inertia-svelte/.gitattributes b/packages/inertia-svelte/.gitattributes new file mode 100644 index 00000000..e5736f06 --- /dev/null +++ b/packages/inertia-svelte/.gitattributes @@ -0,0 +1,5 @@ +/tests export-ignore +/.github export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/phpunit.xml.dist export-ignore diff --git a/packages/inertia-svelte/LICENSE b/packages/inertia-svelte/LICENSE new file mode 100644 index 00000000..99a76f97 --- /dev/null +++ b/packages/inertia-svelte/LICENSE @@ -0,0 +1,20 @@ +MIT License + +Copyright (c) Devtomic LLC + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/inertia-svelte/README.md b/packages/inertia-svelte/README.md new file mode 100644 index 00000000..8a43b210 --- /dev/null +++ b/packages/inertia-svelte/README.md @@ -0,0 +1,60 @@ +# Marko Inertia Svelte + +Configuration defaults for Svelte apps built with `marko/inertia` and `marko/vite`. + +## Install + +```bash +composer require marko/inertia marko/inertia-svelte marko/vite +npm install @inertiajs/svelte@^3.0 svelte@^5.46 @sveltejs/vite-plugin-svelte@^7.0 vite@^8.0 +``` + +## Files + +Create the client entry at `app/svelte-web/resources/js/app.js`: + +```js +import { createInertiaApp } from '@inertiajs/svelte'; +import { mount } from 'svelte'; + +createInertiaApp({ + resolve: (name) => { + const pages = import.meta.glob('./Pages/**/*.svelte', { eager: true }); + return pages[`./Pages/${name}.svelte`]; + }, + setup({ el, App, props }) { + mount(App, { target: el, props }); + }, +}); +``` + +Create the SSR entry at `app/svelte-web/resources/js/ssr.js`: + +```js +import { createInertiaApp } from '@inertiajs/svelte'; +import createServer from '@inertiajs/svelte/server'; +import { render } from 'svelte/server'; + +createServer((page) => + createInertiaApp({ + page, + resolve: (name) => { + const pages = import.meta.glob('./Pages/**/*.svelte', { eager: true }); + return pages[`./Pages/${name}.svelte`]; + }, + setup({ App, props }) { + return render(App, { props }); + }, + }), +); +``` + +## Configuration + +The package exposes: + +- `clientEntry`: `app/svelte-web/resources/js/app.js` +- `ssrEntry`: `app/svelte-web/resources/js/ssr.js` +- `ssrBundle`: `bootstrap/ssr/svelte/ssr.js` + +Override them with `INERTIA_SVELTE_CLIENT_ENTRY`, `INERTIA_SVELTE_SSR_ENTRY`, and `INERTIA_SVELTE_SSR_BUNDLE`. diff --git a/packages/inertia-svelte/composer.json b/packages/inertia-svelte/composer.json new file mode 100644 index 00000000..7a5c9b85 --- /dev/null +++ b/packages/inertia-svelte/composer.json @@ -0,0 +1,28 @@ +{ + "name": "marko/inertia-svelte", + "type": "marko-module", + "description": "Svelte companion for marko/inertia — configuration for Svelte client and SSR entries", + "license": "MIT", + "require": { + "php": "^8.5", + "marko/core": "self.version", + "marko/env": "self.version", + "marko/inertia": "self.version", + "marko/vite": "self.version" + }, + "autoload": { + "psr-4": { + "Marko\\InertiaSvelte\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Marko\\InertiaSvelte\\Tests\\": "tests/" + } + }, + "extra": { + "marko": { + "module": true + } + } +} diff --git a/packages/inertia-svelte/config/inertia-svelte.php b/packages/inertia-svelte/config/inertia-svelte.php new file mode 100644 index 00000000..217f1993 --- /dev/null +++ b/packages/inertia-svelte/config/inertia-svelte.php @@ -0,0 +1,14 @@ + env('INERTIA_SVELTE_CLIENT_ENTRY', 'app/svelte-web/resources/js/app.js'), + 'ssrEntry' => env('INERTIA_SVELTE_SSR_ENTRY', 'app/svelte-web/resources/js/ssr.js'), + 'ssrBundle' => env('INERTIA_SVELTE_SSR_BUNDLE', $basePath.'/bootstrap/ssr/svelte/ssr.js'), +]; diff --git a/packages/inertia-svelte/module.php b/packages/inertia-svelte/module.php new file mode 100644 index 00000000..12a179a2 --- /dev/null +++ b/packages/inertia-svelte/module.php @@ -0,0 +1,10 @@ + true, + 'sequence' => [ + 'after' => ['marko/inertia', 'marko/vite'], + ], +]; diff --git a/packages/inertia-svelte/tests/InertiaSvelteTest.php b/packages/inertia-svelte/tests/InertiaSvelteTest.php new file mode 100644 index 00000000..121c2cb1 --- /dev/null +++ b/packages/inertia-svelte/tests/InertiaSvelteTest.php @@ -0,0 +1,19 @@ +toBe('app/svelte-web/resources/js/app.js'); + expect($config['ssrEntry'])->toBe('app/svelte-web/resources/js/ssr.js'); + expect($config['ssrBundle'])->toEndWith('/bootstrap/ssr/svelte/ssr.js'); +}); + +test('inertia-svelte module depends on inertia and vite', function () { + $module = require dirname(__DIR__).'/module.php'; + + expect($module['enabled'])->toBeTrue(); + expect($module['sequence']['after'])->toContain('marko/inertia'); + expect($module['sequence']['after'])->toContain('marko/vite'); +}); From 5b3f3dc2f74a7076dd7b26f1778416e00e0b9a56 Mon Sep 17 00:00:00 2001 From: Paulo Carvalho Date: Fri, 1 May 2026 20:38:40 +0100 Subject: [PATCH 2/4] refactor: align marko/inertia-svelte with package conventions and add docs page --- .../content/docs/packages/inertia-svelte.md | 110 ++++++++++++++++++ packages/inertia-svelte/.gitattributes | 2 +- packages/inertia-svelte/README.md | 79 +++++-------- packages/inertia-svelte/composer.json | 45 ++++--- .../inertia-svelte/config/inertia-svelte.php | 7 +- packages/inertia-svelte/module.php | 10 -- .../tests/InertiaSvelteTest.php | 15 ++- 7 files changed, 169 insertions(+), 99 deletions(-) create mode 100644 docs/src/content/docs/packages/inertia-svelte.md delete mode 100644 packages/inertia-svelte/module.php diff --git a/docs/src/content/docs/packages/inertia-svelte.md b/docs/src/content/docs/packages/inertia-svelte.md new file mode 100644 index 00000000..29e4c289 --- /dev/null +++ b/docs/src/content/docs/packages/inertia-svelte.md @@ -0,0 +1,110 @@ +--- +title: marko/inertia-svelte +description: Svelte companion for marko/inertia - configuration defaults for Svelte client and SSR entries. +--- + +Svelte companion for [`marko/inertia`](/docs/packages/inertia/) and [`marko/vite`](/docs/packages/vite/). It ships Marko configuration defaults for Svelte client and SSR entrypoints while leaving the JavaScript application code in your project. + +## Installation + +```bash +composer require marko/inertia-svelte +``` + +Install the matching frontend dependencies in your app: + +```bash +npm install @inertiajs/svelte@^3.0 svelte@^5.46 @sveltejs/vite-plugin-svelte@^7.0 vite@^8.0 +``` + +## Configuration + +Configure via `config/inertia-svelte.php`: + +```php title="config/inertia-svelte.php" +return [ + 'clientEntry' => env('INERTIA_SVELTE_CLIENT_ENTRY', 'app/svelte-web/resources/js/app.js'), + 'ssrEntry' => env('INERTIA_SVELTE_SSR_ENTRY', 'app/svelte-web/resources/js/ssr.js'), + 'ssrBundle' => env('INERTIA_SVELTE_SSR_BUNDLE', 'bootstrap/ssr/svelte/ssr.js'), +]; +``` + +| Key | Purpose | +| --- | --- | +| `clientEntry` | Vite entry used by browser-rendered Inertia responses. | +| `ssrEntry` | Vite entry used to build the Svelte SSR server bundle. | +| `ssrBundle` | Relative path to the built SSR bundle loaded by your SSR runner. | + +## Usage + +Use the configured client entry when rendering Svelte-backed Inertia pages: + +```php +use Marko\Inertia\Inertia; +use Marko\Routing\Http\Request; +use Marko\Routing\Http\Response; + +class DashboardController +{ + public function __construct( + private readonly Inertia $inertia, + ) {} + + public function index(Request $request): Response + { + return $this->inertia->render( + request: $request, + component: 'Dashboard', + assetEntry: 'app/svelte-web/resources/js/app.js', + ); + } +} +``` + +Create the client entry at `app/svelte-web/resources/js/app.js`: + +```js title="app/svelte-web/resources/js/app.js" +import { createInertiaApp } from '@inertiajs/svelte'; +import { mount } from 'svelte'; + +createInertiaApp({ + resolve: (name) => { + const pages = import.meta.glob('./Pages/**/*.svelte', { eager: true }); + return pages[`./Pages/${name}.svelte`]; + }, + setup({ el, App, props }) { + mount(App, { target: el, props }); + }, +}); +``` + +Create the SSR entry at `app/svelte-web/resources/js/ssr.js`: + +```js title="app/svelte-web/resources/js/ssr.js" +import { createInertiaApp } from '@inertiajs/svelte'; +import createServer from '@inertiajs/svelte/server'; +import { render } from 'svelte/server'; + +createServer((page) => + createInertiaApp({ + page, + resolve: (name) => { + const pages = import.meta.glob('./Pages/**/*.svelte', { eager: true }); + return pages[`./Pages/${name}.svelte`]; + }, + setup({ App, props }) { + return render(App, { props }); + }, + }), +); +``` + +## API Reference + +This package is configuration-only. It does not add PHP services or bindings; `module.php` is intentionally omitted because Marko can discover the package through Composer metadata and load its `config/` directory without explicit module options. + +## Related Packages + +- [`marko/inertia`](/docs/packages/inertia/) - renders Inertia responses and handles SSR fallback +- [`marko/vite`](/docs/packages/vite/) - resolves the configured Svelte Vite entry +- [`marko/env`](/docs/packages/env/) - provides the `env()` helper used in `config/inertia-svelte.php` diff --git a/packages/inertia-svelte/.gitattributes b/packages/inertia-svelte/.gitattributes index e5736f06..aa78278f 100644 --- a/packages/inertia-svelte/.gitattributes +++ b/packages/inertia-svelte/.gitattributes @@ -1,5 +1,5 @@ /tests export-ignore -/.github export-ignore +/.github export-ignore /.gitattributes export-ignore /.gitignore export-ignore /phpunit.xml.dist export-ignore diff --git a/packages/inertia-svelte/README.md b/packages/inertia-svelte/README.md index 8a43b210..28089bf5 100644 --- a/packages/inertia-svelte/README.md +++ b/packages/inertia-svelte/README.md @@ -1,60 +1,37 @@ -# Marko Inertia Svelte +# marko/inertia-svelte -Configuration defaults for Svelte apps built with `marko/inertia` and `marko/vite`. +Svelte companion for `marko/inertia` - configuration for Svelte client and SSR entries. -## Install +## Installation ```bash -composer require marko/inertia marko/inertia-svelte marko/vite -npm install @inertiajs/svelte@^3.0 svelte@^5.46 @sveltejs/vite-plugin-svelte@^7.0 vite@^8.0 +composer require marko/inertia-svelte ``` -## Files - -Create the client entry at `app/svelte-web/resources/js/app.js`: - -```js -import { createInertiaApp } from '@inertiajs/svelte'; -import { mount } from 'svelte'; - -createInertiaApp({ - resolve: (name) => { - const pages = import.meta.glob('./Pages/**/*.svelte', { eager: true }); - return pages[`./Pages/${name}.svelte`]; - }, - setup({ el, App, props }) { - mount(App, { target: el, props }); - }, -}); +## Quick Example + +```php +use Marko\Inertia\Inertia; +use Marko\Routing\Http\Request; +use Marko\Routing\Http\Response; + +class DashboardController +{ + public function __construct( + private readonly Inertia $inertia, + ) {} + + public function index(Request $request): Response + { + return $this->inertia->render( + request: $request, + component: 'Dashboard', + assetEntry: 'app/svelte-web/resources/js/app.js', + ); + } +} ``` -Create the SSR entry at `app/svelte-web/resources/js/ssr.js`: - -```js -import { createInertiaApp } from '@inertiajs/svelte'; -import createServer from '@inertiajs/svelte/server'; -import { render } from 'svelte/server'; - -createServer((page) => - createInertiaApp({ - page, - resolve: (name) => { - const pages = import.meta.glob('./Pages/**/*.svelte', { eager: true }); - return pages[`./Pages/${name}.svelte`]; - }, - setup({ App, props }) { - return render(App, { props }); - }, - }), -); -``` - -## Configuration - -The package exposes: - -- `clientEntry`: `app/svelte-web/resources/js/app.js` -- `ssrEntry`: `app/svelte-web/resources/js/ssr.js` -- `ssrBundle`: `bootstrap/ssr/svelte/ssr.js` +## Documentation -Override them with `INERTIA_SVELTE_CLIENT_ENTRY`, `INERTIA_SVELTE_SSR_ENTRY`, and `INERTIA_SVELTE_SSR_BUNDLE`. +Full usage, API reference, and examples: [marko/inertia-svelte](https://marko.build/docs/packages/inertia-svelte/) diff --git a/packages/inertia-svelte/composer.json b/packages/inertia-svelte/composer.json index 7a5c9b85..3ceec016 100644 --- a/packages/inertia-svelte/composer.json +++ b/packages/inertia-svelte/composer.json @@ -1,28 +1,23 @@ { - "name": "marko/inertia-svelte", - "type": "marko-module", - "description": "Svelte companion for marko/inertia — configuration for Svelte client and SSR entries", - "license": "MIT", - "require": { - "php": "^8.5", - "marko/core": "self.version", - "marko/env": "self.version", - "marko/inertia": "self.version", - "marko/vite": "self.version" - }, - "autoload": { - "psr-4": { - "Marko\\InertiaSvelte\\": "src/" + "name": "marko/inertia-svelte", + "description": "Svelte companion for marko/inertia - configuration for Svelte client and SSR entries", + "license": "MIT", + "type": "marko-module", + "require": { + "php": "^8.5", + "marko/core": "self.version", + "marko/env": "self.version", + "marko/inertia": "self.version", + "marko/vite": "self.version" + }, + "autoload-dev": { + "psr-4": { + "Marko\\InertiaSvelte\\Tests\\": "tests/" + } + }, + "extra": { + "marko": { + "module": true + } } - }, - "autoload-dev": { - "psr-4": { - "Marko\\InertiaSvelte\\Tests\\": "tests/" - } - }, - "extra": { - "marko": { - "module": true - } - } } diff --git a/packages/inertia-svelte/config/inertia-svelte.php b/packages/inertia-svelte/config/inertia-svelte.php index 217f1993..c208529f 100644 --- a/packages/inertia-svelte/config/inertia-svelte.php +++ b/packages/inertia-svelte/config/inertia-svelte.php @@ -2,13 +2,8 @@ declare(strict_types=1); -$documentRoot = $_SERVER['DOCUMENT_ROOT'] ?? null; -$basePath = is_string($documentRoot) && $documentRoot !== '' - ? dirname($documentRoot) - : (getcwd() ?: ''); - return [ 'clientEntry' => env('INERTIA_SVELTE_CLIENT_ENTRY', 'app/svelte-web/resources/js/app.js'), 'ssrEntry' => env('INERTIA_SVELTE_SSR_ENTRY', 'app/svelte-web/resources/js/ssr.js'), - 'ssrBundle' => env('INERTIA_SVELTE_SSR_BUNDLE', $basePath.'/bootstrap/ssr/svelte/ssr.js'), + 'ssrBundle' => env('INERTIA_SVELTE_SSR_BUNDLE', 'bootstrap/ssr/svelte/ssr.js'), ]; diff --git a/packages/inertia-svelte/module.php b/packages/inertia-svelte/module.php deleted file mode 100644 index 12a179a2..00000000 --- a/packages/inertia-svelte/module.php +++ /dev/null @@ -1,10 +0,0 @@ - true, - 'sequence' => [ - 'after' => ['marko/inertia', 'marko/vite'], - ], -]; diff --git a/packages/inertia-svelte/tests/InertiaSvelteTest.php b/packages/inertia-svelte/tests/InertiaSvelteTest.php index 121c2cb1..96af2bbf 100644 --- a/packages/inertia-svelte/tests/InertiaSvelteTest.php +++ b/packages/inertia-svelte/tests/InertiaSvelteTest.php @@ -7,13 +7,16 @@ expect($config['clientEntry'])->toBe('app/svelte-web/resources/js/app.js'); expect($config['ssrEntry'])->toBe('app/svelte-web/resources/js/ssr.js'); - expect($config['ssrBundle'])->toEndWith('/bootstrap/ssr/svelte/ssr.js'); + expect($config['ssrBundle'])->toBe('bootstrap/ssr/svelte/ssr.js'); }); -test('inertia-svelte module depends on inertia and vite', function () { - $module = require dirname(__DIR__).'/module.php'; +test('inertia-svelte is a config-only marko module', function () { + $composer = json_decode( + file_get_contents(dirname(__DIR__).'/composer.json'), + true, + flags: JSON_THROW_ON_ERROR, + ); - expect($module['enabled'])->toBeTrue(); - expect($module['sequence']['after'])->toContain('marko/inertia'); - expect($module['sequence']['after'])->toContain('marko/vite'); + expect(file_exists(dirname(__DIR__).'/module.php'))->toBeFalse() + ->and($composer['extra']['marko']['module'])->toBeTrue(); }); From 9d6df20a6b29daf06236c6aab64ed7c7b8bf63d5 Mon Sep 17 00:00:00 2001 From: Paulo Carvalho Date: Fri, 1 May 2026 23:21:46 +0100 Subject: [PATCH 3/4] refactor: wire inertia svelte companion through parent config --- .../content/docs/packages/inertia-svelte.md | 31 ++++++++++--------- packages/inertia-svelte/README.md | 3 +- packages/inertia-svelte/composer.json | 7 ++++- .../inertia-svelte/config/inertia-svelte.php | 9 ------ packages/inertia-svelte/config/inertia.php | 10 ++++++ packages/inertia-svelte/module.php | 12 +++++++ .../src/SvelteInertiaFrontend.php | 15 +++++++++ .../tests/InertiaSvelteTest.php | 31 ++++++++++++++----- 8 files changed, 83 insertions(+), 35 deletions(-) delete mode 100644 packages/inertia-svelte/config/inertia-svelte.php create mode 100644 packages/inertia-svelte/config/inertia.php create mode 100644 packages/inertia-svelte/module.php create mode 100644 packages/inertia-svelte/src/SvelteInertiaFrontend.php diff --git a/docs/src/content/docs/packages/inertia-svelte.md b/docs/src/content/docs/packages/inertia-svelte.md index 29e4c289..ca4649c6 100644 --- a/docs/src/content/docs/packages/inertia-svelte.md +++ b/docs/src/content/docs/packages/inertia-svelte.md @@ -1,9 +1,9 @@ --- title: marko/inertia-svelte -description: Svelte companion for marko/inertia - configuration defaults for Svelte client and SSR entries. +description: Svelte companion for marko/inertia - configuration defaults and a frontend marker binding for Svelte. --- -Svelte companion for [`marko/inertia`](/docs/packages/inertia/) and [`marko/vite`](/docs/packages/vite/). It ships Marko configuration defaults for Svelte client and SSR entrypoints while leaving the JavaScript application code in your project. +Svelte companion for [`marko/inertia`](/docs/packages/inertia/) and [`marko/vite`](/docs/packages/vite/). It overlays the parent Inertia configuration with Svelte defaults and registers a frontend marker binding so installing multiple Inertia frontend companions fails loudly. ## Installation @@ -14,30 +14,32 @@ composer require marko/inertia-svelte Install the matching frontend dependencies in your app: ```bash -npm install @inertiajs/svelte@^3.0 svelte@^5.46 @sveltejs/vite-plugin-svelte@^7.0 vite@^8.0 +npm install @inertiajs/svelte svelte @sveltejs/vite-plugin-svelte vite ``` +Refer to the Inertia.js docs for currently supported versions of each frontend adapter. + ## Configuration -Configure via `config/inertia-svelte.php`: +This package contributes defaults to the parent `config/inertia.php` namespace: -```php title="config/inertia-svelte.php" +```php title="packages/inertia-svelte/config/inertia.php" return [ - 'clientEntry' => env('INERTIA_SVELTE_CLIENT_ENTRY', 'app/svelte-web/resources/js/app.js'), - 'ssrEntry' => env('INERTIA_SVELTE_SSR_ENTRY', 'app/svelte-web/resources/js/ssr.js'), - 'ssrBundle' => env('INERTIA_SVELTE_SSR_BUNDLE', 'bootstrap/ssr/svelte/ssr.js'), + 'assetEntry' => env('INERTIA_SVELTE_CLIENT_ENTRY', 'app/svelte-web/resources/js/app.js'), + 'ssr' => [ + 'bundle' => env('INERTIA_SVELTE_SSR_BUNDLE', 'bootstrap/ssr/svelte/ssr.js'), + ], ]; ``` | Key | Purpose | | --- | --- | -| `clientEntry` | Vite entry used by browser-rendered Inertia responses. | -| `ssrEntry` | Vite entry used to build the Svelte SSR server bundle. | -| `ssrBundle` | Relative path to the built SSR bundle loaded by your SSR runner. | +| `assetEntry` | Vite entry used by browser-rendered Inertia responses. | +| `ssr.bundle` | Relative path to the built SSR bundle loaded by your SSR runner. | ## Usage -Use the configured client entry when rendering Svelte-backed Inertia pages: +Render Svelte-backed Inertia pages without passing an asset entry; `marko/inertia` reads it from configuration: ```php use Marko\Inertia\Inertia; @@ -55,7 +57,6 @@ class DashboardController return $this->inertia->render( request: $request, component: 'Dashboard', - assetEntry: 'app/svelte-web/resources/js/app.js', ); } } @@ -101,10 +102,10 @@ createServer((page) => ## API Reference -This package is configuration-only. It does not add PHP services or bindings; `module.php` is intentionally omitted because Marko can discover the package through Composer metadata and load its `config/` directory without explicit module options. +This package registers `Marko\Inertia\Frontend\InertiaFrontendInterface` to a Svelte marker implementation. Installing more than one Inertia frontend companion produces the same binding conflict protection used by Marko driver siblings. ## Related Packages - [`marko/inertia`](/docs/packages/inertia/) - renders Inertia responses and handles SSR fallback - [`marko/vite`](/docs/packages/vite/) - resolves the configured Svelte Vite entry -- [`marko/env`](/docs/packages/env/) - provides the `env()` helper used in `config/inertia-svelte.php` +- [`marko/env`](/docs/packages/env/) - provides the `env()` helper used in `config/inertia.php` diff --git a/packages/inertia-svelte/README.md b/packages/inertia-svelte/README.md index 28089bf5..2ca0a8f0 100644 --- a/packages/inertia-svelte/README.md +++ b/packages/inertia-svelte/README.md @@ -1,6 +1,6 @@ # marko/inertia-svelte -Svelte companion for `marko/inertia` - configuration for Svelte client and SSR entries. +Svelte companion for `marko/inertia` - configuration defaults and a frontend marker binding for Svelte. ## Installation @@ -26,7 +26,6 @@ class DashboardController return $this->inertia->render( request: $request, component: 'Dashboard', - assetEntry: 'app/svelte-web/resources/js/app.js', ); } } diff --git a/packages/inertia-svelte/composer.json b/packages/inertia-svelte/composer.json index 3ceec016..69f23106 100644 --- a/packages/inertia-svelte/composer.json +++ b/packages/inertia-svelte/composer.json @@ -1,6 +1,6 @@ { "name": "marko/inertia-svelte", - "description": "Svelte companion for marko/inertia - configuration for Svelte client and SSR entries", + "description": "Svelte companion for marko/inertia - configuration and frontend marker binding", "license": "MIT", "type": "marko-module", "require": { @@ -10,6 +10,11 @@ "marko/inertia": "self.version", "marko/vite": "self.version" }, + "autoload": { + "psr-4": { + "Marko\\Inertia\\Svelte\\": "src/" + } + }, "autoload-dev": { "psr-4": { "Marko\\InertiaSvelte\\Tests\\": "tests/" diff --git a/packages/inertia-svelte/config/inertia-svelte.php b/packages/inertia-svelte/config/inertia-svelte.php deleted file mode 100644 index c208529f..00000000 --- a/packages/inertia-svelte/config/inertia-svelte.php +++ /dev/null @@ -1,9 +0,0 @@ - env('INERTIA_SVELTE_CLIENT_ENTRY', 'app/svelte-web/resources/js/app.js'), - 'ssrEntry' => env('INERTIA_SVELTE_SSR_ENTRY', 'app/svelte-web/resources/js/ssr.js'), - 'ssrBundle' => env('INERTIA_SVELTE_SSR_BUNDLE', 'bootstrap/ssr/svelte/ssr.js'), -]; diff --git a/packages/inertia-svelte/config/inertia.php b/packages/inertia-svelte/config/inertia.php new file mode 100644 index 00000000..5c51a883 --- /dev/null +++ b/packages/inertia-svelte/config/inertia.php @@ -0,0 +1,10 @@ + env('INERTIA_SVELTE_CLIENT_ENTRY', 'app/svelte-web/resources/js/app.js'), + 'ssr' => [ + 'bundle' => env('INERTIA_SVELTE_SSR_BUNDLE', 'bootstrap/ssr/svelte/ssr.js'), + ], +]; diff --git a/packages/inertia-svelte/module.php b/packages/inertia-svelte/module.php new file mode 100644 index 00000000..d2d12f8c --- /dev/null +++ b/packages/inertia-svelte/module.php @@ -0,0 +1,12 @@ + [ + InertiaFrontendInterface::class => SvelteInertiaFrontend::class, + ], +]; diff --git a/packages/inertia-svelte/src/SvelteInertiaFrontend.php b/packages/inertia-svelte/src/SvelteInertiaFrontend.php new file mode 100644 index 00000000..ba618b77 --- /dev/null +++ b/packages/inertia-svelte/src/SvelteInertiaFrontend.php @@ -0,0 +1,15 @@ +toBe('app/svelte-web/resources/js/app.js'); - expect($config['ssrEntry'])->toBe('app/svelte-web/resources/js/ssr.js'); - expect($config['ssrBundle'])->toBe('bootstrap/ssr/svelte/ssr.js'); +test('inertia-svelte config overlays the parent inertia config', function () { + $config = require dirname(__DIR__).'/config/inertia.php'; + + expect($config['assetEntry'])->toBe('app/svelte-web/resources/js/app.js'); + expect($config['ssr']['bundle'])->toBe('bootstrap/ssr/svelte/ssr.js'); + expect($config)->not->toHaveKey('ssrEntry'); +}); + +test('inertia-svelte binds the inertia frontend marker', function () { + $module = require dirname(__DIR__).'/module.php'; + + expect($module['bindings'])->toHaveKey(InertiaFrontendInterface::class) + ->and($module['bindings'][InertiaFrontendInterface::class])->toBe(SvelteInertiaFrontend::class); +}); + +test('svelte inertia frontend identifies itself', function () { + expect((new SvelteInertiaFrontend())->name())->toBe('svelte'); }); -test('inertia-svelte is a config-only marko module', function () { +test('inertia-svelte is a marko module', function () { $composer = json_decode( file_get_contents(dirname(__DIR__).'/composer.json'), true, flags: JSON_THROW_ON_ERROR, ); - expect(file_exists(dirname(__DIR__).'/module.php'))->toBeFalse() - ->and($composer['extra']['marko']['module'])->toBeTrue(); + expect(file_exists(dirname(__DIR__).'/module.php'))->toBeTrue() + ->and($composer['extra']['marko']['module'])->toBeTrue() + ->and($composer['autoload']['psr-4'])->toHaveKey('Marko\\Inertia\\Svelte\\'); }); From 866b6b5af63ed4b5caea45ac2139957c85a90066 Mon Sep 17 00:00:00 2001 From: Mark Shust Date: Fri, 1 May 2026 20:45:19 -0400 Subject: [PATCH 4/4] refactor: align inertia-svelte with sibling conventions and trim pseudo-config - Nest test namespace as Marko\Inertia\Svelte\Tests\ to match every other Marko driver sibling (Marko\Cache\File\Tests\, Marko\Database\PgSql\Tests\) - Drop ssr.bundle config slot from companion and parent (no PHP consumer; Marko's SSR client only reads inertia.ssr.enabled and inertia.ssr.url) - Link the Inertia.js docs reference in the npm install note - Document the inertia.assetEntry overlay slot in the parent inertia docs Closes #17. Co-Authored-By: Paulo Carvalho Co-Authored-By: Claude Opus 4.7 (1M context) --- composer.json | 2 +- docs/src/content/docs/packages/inertia-svelte.md | 6 +----- packages/inertia-svelte/composer.json | 2 +- packages/inertia-svelte/config/inertia.php | 3 --- packages/inertia-svelte/tests/InertiaSvelteTest.php | 1 - 5 files changed, 3 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 180e12e2..376835e5 100644 --- a/composer.json +++ b/composer.json @@ -463,7 +463,7 @@ "Marko\\Health\\Tests\\": "packages/health/tests/", "Marko\\Inertia\\Tests\\": "packages/inertia/tests/", "Marko\\Inertia\\React\\Tests\\": "packages/inertia-react/tests/", - "Marko\\InertiaSvelte\\Tests\\": "packages/inertia-svelte/tests/", + "Marko\\Inertia\\Svelte\\Tests\\": "packages/inertia-svelte/tests/", "Marko\\Inertia\\Vue\\Tests\\": "packages/inertia-vue/tests/", "Marko\\Http\\Tests\\": "packages/http/tests/", "Marko\\Http\\Guzzle\\Tests\\": "packages/http-guzzle/tests/", diff --git a/docs/src/content/docs/packages/inertia-svelte.md b/docs/src/content/docs/packages/inertia-svelte.md index ca4649c6..4cb01581 100644 --- a/docs/src/content/docs/packages/inertia-svelte.md +++ b/docs/src/content/docs/packages/inertia-svelte.md @@ -17,7 +17,7 @@ Install the matching frontend dependencies in your app: npm install @inertiajs/svelte svelte @sveltejs/vite-plugin-svelte vite ``` -Refer to the Inertia.js docs for currently supported versions of each frontend adapter. +Refer to the [Inertia.js docs](https://inertiajs.com/) for currently supported versions of each frontend adapter. ## Configuration @@ -26,16 +26,12 @@ This package contributes defaults to the parent `config/inertia.php` namespace: ```php title="packages/inertia-svelte/config/inertia.php" return [ 'assetEntry' => env('INERTIA_SVELTE_CLIENT_ENTRY', 'app/svelte-web/resources/js/app.js'), - 'ssr' => [ - 'bundle' => env('INERTIA_SVELTE_SSR_BUNDLE', 'bootstrap/ssr/svelte/ssr.js'), - ], ]; ``` | Key | Purpose | | --- | --- | | `assetEntry` | Vite entry used by browser-rendered Inertia responses. | -| `ssr.bundle` | Relative path to the built SSR bundle loaded by your SSR runner. | ## Usage diff --git a/packages/inertia-svelte/composer.json b/packages/inertia-svelte/composer.json index 69f23106..3640b57b 100644 --- a/packages/inertia-svelte/composer.json +++ b/packages/inertia-svelte/composer.json @@ -17,7 +17,7 @@ }, "autoload-dev": { "psr-4": { - "Marko\\InertiaSvelte\\Tests\\": "tests/" + "Marko\\Inertia\\Svelte\\Tests\\": "tests/" } }, "extra": { diff --git a/packages/inertia-svelte/config/inertia.php b/packages/inertia-svelte/config/inertia.php index 5c51a883..ffbaf168 100644 --- a/packages/inertia-svelte/config/inertia.php +++ b/packages/inertia-svelte/config/inertia.php @@ -4,7 +4,4 @@ return [ 'assetEntry' => env('INERTIA_SVELTE_CLIENT_ENTRY', 'app/svelte-web/resources/js/app.js'), - 'ssr' => [ - 'bundle' => env('INERTIA_SVELTE_SSR_BUNDLE', 'bootstrap/ssr/svelte/ssr.js'), - ], ]; diff --git a/packages/inertia-svelte/tests/InertiaSvelteTest.php b/packages/inertia-svelte/tests/InertiaSvelteTest.php index 2efec7f7..2dc448fe 100644 --- a/packages/inertia-svelte/tests/InertiaSvelteTest.php +++ b/packages/inertia-svelte/tests/InertiaSvelteTest.php @@ -9,7 +9,6 @@ $config = require dirname(__DIR__).'/config/inertia.php'; expect($config['assetEntry'])->toBe('app/svelte-web/resources/js/app.js'); - expect($config['ssr']['bundle'])->toBe('bootstrap/ssr/svelte/ssr.js'); expect($config)->not->toHaveKey('ssrEntry'); });