Skip to content

Instantly share code, notes, and snippets.

@innocenzi
Last active November 21, 2022 13:41
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save innocenzi/f43e815c1ab9168ce4409c37f2f6ac51 to your computer and use it in GitHub Desktop.
Save innocenzi/f43e815c1ab9168ce4409c37f2f6ac51 to your computer and use it in GitHub Desktop.
Vite + Inertia SSR

package.json:

{
  "scripts": {
    "dev": "vite",
    "dev:server": "node public/build/server/server.js",
    "build": "vite build",
    "build:server": "vite build --outDir ./public/build/server --ssr ./resources/scripts/inertia/server.ts"
  }
}

Main issue: in vite.php you need to manually add the server.ts to the entrypoints when you want to bundle for SSR using npm run build:server

Developing (in two separate terminals):

npm run dev
npm run dev:server

Didn't try the production build, but should be straightforward

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
@vite
@inertiaHead
</head>
<body class="antialiased">
@inertia
</body>
</html>
// resources/scripts/inertia/server.ts
import { createSSRApp, h } from 'vue'
import { renderToString } from '@vue/server-renderer'
import { createInertiaApp } from '@inertiajs/inertia-vue3'
import { withVite } from './inertia/with-vite'
import createServer from '@inertiajs/server'
createServer((page) => createInertiaApp({
page,
render: renderToString,
resolve: (name) => withVite(import.meta.glob('../../views/pages/**/*.vue'), name),
setup({ app, props, plugin }) {
return createSSRApp({
render: () => h(app, props),
}).use(plugin)
},
}))
// config/vite,php
<?php
return [
/*
|--------------------------------------------------------------------------
| Entrypoints
|--------------------------------------------------------------------------
| The files in the configured directories will be considered
| entry points and will not be required in the configuration file.
| To disable the feature, set to false.
*/
'entrypoints' => [
'resources/scripts/main.ts',
// 'resources/scripts/inertia/server.ts', // uncomment when building for SSR, recomment when starting dev server
],
'ignore_patterns' => [
'/\\.d\\.ts$/',
'/\\.json$/',
],
/*
|--------------------------------------------------------------------------
| Aliases
|--------------------------------------------------------------------------
| These aliases will be added to the Vite configuration and used
| to generate a proper tsconfig.json file.
*/
'aliases' => [
'@' => 'resources',
],
/*
|--------------------------------------------------------------------------
| Static assets path
|--------------------------------------------------------------------------
| This option defines the directory that Vite considers as the
| public directory. Its content will be copied to the build directory
| at build-time.
| https://vitejs.dev/config/#publicdir
*/
'public_directory' => resource_path('static'),
/*
|--------------------------------------------------------------------------
| Ping timeout
|--------------------------------------------------------------------------
| The maximum duration, in seconds, that the ping to `ping_url` or
| `dev_url` should take while trying to determine whether to use the
| manifest or the server in a local environment. Using false will disable
| the feature.
| https://laravel-vite.innocenzi.dev/guide/configuration.html#ping-timeout
*/
'ping_timeout' => 10,
'ping_url' => null,
/*
|--------------------------------------------------------------------------
| Build path
|--------------------------------------------------------------------------
| The directory, relative to /public, in which Vite will build
| the production files. This should match "build.outDir" in the Vite
| configuration file.
*/
'build_path' => 'build',
/*
|--------------------------------------------------------------------------
| Development URL
|--------------------------------------------------------------------------
| The URL at which the Vite development server runs.
| This is used to generate the script tags when developing.
*/
'dev_url' => env('VITE_DEV_SERVER_URL', 'https://localhost:3000'),
/*
|--------------------------------------------------------------------------
| Commands
|--------------------------------------------------------------------------
| Defines the list of artisan commands that will be executed when
| the development server or the production build starts.
*/
'commands' => [
'vite:aliases',
// 'typescript:generate'
],
];
// resources/scripts/inertia/with-vite.ts
export function withVite(pages: Record<string, any>, name: string) {
for (const path in pages) {
if (path.endsWith(`${name.replace('.', '/')}.vue`)) {
return typeof pages[path] === 'function'
? pages[path]()
: pages[path]
}
}
throw new Error('Page not found: ' + name)
}
@RomkaLTU
Copy link

Doesn't work.

TypeError: createServer is not a function

@duswie
Copy link

duswie commented Nov 21, 2022

Try to add this to your vite.config.js :

export default defineConfig({
    ...
    ssr: {
        noExternal: ['@inertiajs/server'],
    },
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment