inertiajs / inertia-laravel

The Laravel adapter for Inertia.js.
https://inertiajs.com
MIT License
2.03k stars 227 forks source link

What's the proper way to SSR with Vite/Jetstream/Ziggy/Inertia ? #530

Closed BryanMeurisse closed 1 year ago

BryanMeurisse commented 1 year ago

Can't find a way to make it happen, i've tried 200 ways except the right one... I'm actually using a custom port for the SSR as it's not my only SSR project on my server, so using 13175 instead of 13174.

[Vue warn]: Unhandled error during execution of setup function at <Welcome jetstream= { ... managesProfilePhotos: true } auth= { user: null } errorBags= [] ... > ReferenceError: route is not defined

package.json

{
    "private": true,
    "scripts": {
        "dev": "vite",
        "build": "vite build && vite build --ssr",
        "build-features": "cd nova-components/Features && npm run dev",
        "build-features-prod": "cd nova-components/Features && npm run prod"
    },
    "devDependencies": {
        "@inertiajs/vue3": "^1.0.1",
        "@tailwindcss/forms": "^0.5.2",
        "@tailwindcss/typography": "^0.5.2",
        "@vitejs/plugin-vue": "^4.0.0",
        "autoprefixer": "^10.4.7",
        "axios": "^1.1.2",
        "laravel-vite-plugin": "^0.7.2",
        "postcss": "^8.4.14",
        "postcss-import": "^15.1.0",
        "postcss-nesting": "^11.2.2",
        "tailwindcss": "^3.2.6",
        "vite": "^4.0.0",
        "vue": "^3.2.41"
    },
    "dependencies": {
        "@headlessui/vue": "^1.7.14",
        "@heroicons/vue": "^2.0.18",
        "@vue/server-renderer": "^3.3.4",
        "dropzone": "^6.0.0-beta.2",
        "puppeteer": "^20.7.3",
        "vue3-carousel": "^0.2.16",
        "ziggy-js": "^1.6.0"
    }
}

composer.json

 "require": {
...
"tightenco/ziggy": "^1.0"
}

app.js

import './bootstrap';
import { createSSRApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/vue3';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m';

createInertiaApp({
    resolve: (name) => resolvePageComponent("./Pages/${name}.vue", import.meta.glob('./Pages/**/*.vue')),
    setup({ el, App, props, plugin }) {
        return createSSRApp({ render: () => h(App, props) })
            .use(ZiggyVue, Ziggy)
            .use(plugin)
            .mount(el)
    },
});

app.ssr

import { createSSRApp, h } from "vue";
import { renderToString } from "@vue/server-renderer";
import { createInertiaApp } from '@inertiajs/vue3';
import createServer from '@inertiajs/vue3/server'
import { resolvePageComponent } from "laravel-vite-plugin/inertia-helpers";

const appName = "Laravel";

createServer((page) =>
    createInertiaApp({
        page,
        render: renderToString,
        title: (title) => `${title} - ${appName}`,
        resolve: (name) =>
            resolvePageComponent(
                `./Pages/${name}.vue`,
                import.meta.glob("./Pages/**/*.vue")
            ),
        setup({ app, props, plugin }) {
            const Ziggy = {
                ...props.initialPage.props.ziggy,
                location: new URL(props.initialPage.props.ziggy.url)
            }

            return createSSRApp({
                render: () => h(app, props),
            }).use(plugin)
        },
    }),13175
);

my layout: app.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title inertia>{{ config('app.name') }}</title>

    <link rel="apple-touch-icon" sizes="180x180" href="/images/favicon_io_/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon_io_/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon_io_/favicon-16x16.png">
    <link rel="manifest" href="/images/favicon_io_/site.webmanifest">

    @routes
    @vite(['resources/css/app.css','resources/js/app.js'])
    @inertiaHead
</head>

<body class="font-sans antialiased">

    @inertia

</body>

</html>

HandleInertiaRequests.php

use Tightenco\Ziggy\Ziggy;

public function share(Request $request): array
    {

        $ziggy = new Ziggy($group = null, $request->url());
        $shared = array_merge(parent::share($request), [
            'ziggy' => $ziggy->toArray(),
        ]);

        return $shared;
    }

vite.config.js

import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    build: {
        rollupOptions: {
            external: ["@heroicons/vue"]
        }
    },
    plugins: [
        laravel({
            input: ['resources/css/app.css','resources/js/app.js'],
            ssr: "resources/js/ssr.js",
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ]
});

config inertia.php

'ssr' => [

        'enabled' => true,

        'url' => 'http://127.0.0.1:13175',

        // 'bundle' => base_path('bootstrap/ssr/ssr.mjs'),

    ],
jessarcher commented 1 year ago

Hi there,

Thanks for reporting the problem you are encountering. I can't replicate the bug on a fresh Jetstream Inertia install (even with a custom port). I noticed that the Ziggy parts of your setup methods in your app.js and ssr.js files are a bit different from the default ones provided by Jetstream, so perhaps try confirming whether the issue exists there and, if not, copying over those parts from the default files.

You can also try one of the following channels:

If you can confirm that there is an issue with this library, please feel free open an issue with a minimal reproduction repository. Thanks!