diff --git a/src/Console/InstallCommand.php b/src/Console/InstallCommand.php index 475c6f78f..4ef2cecf5 100644 --- a/src/Console/InstallCommand.php +++ b/src/Console/InstallCommand.php @@ -19,6 +19,7 @@ class InstallCommand extends Command protected $signature = 'jetstream:install {stack : The development stack that should be installed} {--teams : Indicates if team support should be installed} {--pest : Indicates if Pest should be installed} + {--ssr : Indicates if Inertia SSR support should be installed} {--composer=global : Absolute path to the Composer binary which should be used to install packages}'; /** @@ -403,6 +404,10 @@ protected function installInertiaStack() $this->installInertiaTeamStack(); } + if ($this->option('ssr')) { + $this->installInertiaSsrStack(); + } + $this->line(''); $this->info('Inertia scaffolding installed successfully.'); $this->comment('Please execute "npm install && npm run dev" to build your assets.'); @@ -482,6 +487,34 @@ protected function ensureApplicationIsTeamCompatible() copy(__DIR__.'/../../database/factories/TeamFactory.php', base_path('database/factories/TeamFactory.php')); } + /** + * Install the Inertia SSR stack into the application. + * + * @return void + */ + protected function installInertiaSsrStack() + { + $this->updateNodePackages(function ($packages) { + return [ + '@inertiajs/server' => '^0.1.0', + '@vue/server-renderer' => '^3.2.31', + 'webpack-node-externals' => '^3.0.0', + ] + $packages; + }); + + copy(__DIR__.'/../../stubs/inertia/webpack.ssr.mix.js', base_path('webpack.ssr.mix.js')); + copy(__DIR__.'/../../stubs/inertia/resources/js/ssr.js', resource_path('js/ssr.js')); + + (new Process([$this->phpBinary(), 'artisan', 'vendor:publish', '--provider=Inertia\ServiceProvider', '--force'], base_path())) + ->setTimeout(null) + ->run(function ($type, $output) { + $this->output->write($output); + }); + + $this->replaceInFile("'enabled' => false", "'enabled' => true", config_path('inertia.php')); + $this->replaceInFile('mix --production', 'mix --production --mix-config=webpack.ssr.mix.js && mix --production', base_path('package.json')); + } + /** * Install the service provider in the application configuration file. * diff --git a/src/Http/Middleware/ShareInertiaData.php b/src/Http/Middleware/ShareInertiaData.php index 8928520a0..59c9cfe5a 100644 --- a/src/Http/Middleware/ShareInertiaData.php +++ b/src/Http/Middleware/ShareInertiaData.php @@ -7,6 +7,7 @@ use Inertia\Inertia; use Laravel\Fortify\Features; use Laravel\Jetstream\Jetstream; +use Tightenco\Ziggy\Ziggy; class ShareInertiaData { @@ -56,6 +57,9 @@ public function handle($request, $next) return [$key => $bag->messages()]; })->all(); }, + 'ziggy' => function () { + return (new Ziggy)->toArray(); + }, ])); return $next($request); diff --git a/stubs/inertia/resources/js/ssr.js b/stubs/inertia/resources/js/ssr.js new file mode 100644 index 000000000..59b904cf9 --- /dev/null +++ b/stubs/inertia/resources/js/ssr.js @@ -0,0 +1,30 @@ +import { createSSRApp, h } from 'vue'; +import { renderToString } from '@vue/server-renderer'; +import { createInertiaApp } from '@inertiajs/inertia-vue3'; +import createServer from '@inertiajs/server'; +import route from 'ziggy'; + +const appName = 'Laravel'; + +createServer((page) => + createInertiaApp({ + page, + render: renderToString, + title: (title) => `${title} - ${appName}`, + resolve: (name) => require(`./Pages/${name}.vue`), + setup({ app, props, plugin }) { + return createSSRApp({ render: () => h(app, props) }) + .use(plugin) + .mixin({ + methods: { + route: (name, params, absolute) => { + return route(name, params, absolute, { + ...page.props.ziggy, + location: new URL(page.props.ziggy.url), + }); + }, + }, + }); + }, + }) +); diff --git a/stubs/inertia/resources/views/app.blade.php b/stubs/inertia/resources/views/app.blade.php index fe0e36dd5..f651f27c2 100644 --- a/stubs/inertia/resources/views/app.blade.php +++ b/stubs/inertia/resources/views/app.blade.php @@ -15,6 +15,7 @@ @routes + @inertiaHead @inertia diff --git a/stubs/inertia/webpack.ssr.mix.js b/stubs/inertia/webpack.ssr.mix.js new file mode 100644 index 000000000..6dfaae611 --- /dev/null +++ b/stubs/inertia/webpack.ssr.mix.js @@ -0,0 +1,17 @@ +const mix = require('laravel-mix'); +const webpackNodeExternals = require('webpack-node-externals'); + +mix.js('resources/js/ssr.js', 'public/js') + .vue({ + version: 3, + useVueStyleLoader: true, + options: { optimizeSSR: true }, + }) + .alias({ + '@': 'resources/js', + ziggy: 'vendor/tightenco/ziggy/dist/index', + }) + .webpackConfig({ + target: 'node', + externals: [webpackNodeExternals()], + });