Skip to content

Instantly share code, notes, and snippets.

@innocenzi
Last active April 1, 2023 13:01
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save innocenzi/48d95f99acc70ce8f763112f23147bdb to your computer and use it in GitHub Desktop.
Save innocenzi/48d95f99acc70ce8f763112f23147bdb to your computer and use it in GitHub Desktop.
Laravel + Vite + Inertia SSR
{
"scripts": {
"dev": "npx esno server.ts",
"build": "vite build",
"build:ssr": "vite build --ssr",
"build:all": "npm run build && npm run build:ssr"
}
}
// This is the server that should be ran in dev instead of `vite dev`
// eg. esno server.ts
import * as process from 'node:process'
import { createServer as createViteServer } from 'vite'
import express from 'express'
import body from 'body-parser'
async function createServer() {
const port = 13714
const app = express()
const vite = await createViteServer({
server: { middlewareMode: 'ssr' }
})
app.use(body.json())
app.use(vite.middlewares)
app.use('/health', (_, res) => res.send({ status: 'OK', timestamp: Date.now() }))
app.use('/404', (_, res) => res.send({ status: 'NOT_FOUND', timestamp: Date.now() }))
app.use('/shutdown', () => process.exit())
app.use('/render', async (req, res) => {
console.log(req.body)
const { render } = await vite.ssrLoadModule('/resources/scripts/ssr.ts')
const response = await render(req.body)
res.json(response)
})
app.listen(port || 13714)
console.log(`Listening to Inertia requests on port ${port || 13714}`)
}
createServer()
// This is the server entrypoints that should be included
// by the custom Vite server
import { createSSRApp, h } from 'vue'
import { renderToString } from '@vue/server-renderer'
import { createInertiaApp } from '@inertiajs/inertia-vue3'
import { withVite } from '@/scripts/inertia/with-vite'
import type { Page } from '@inertiajs/inertia'
export function render(page: Page) {
return createInertiaApp({
page,
render: renderToString,
resolve: (name) => withVite(import.meta.globEager('../views/pages/**/*.vue'), name),
setup: ({ app, props, plugin: inertia }) => createSSRApp({
render: () => h(app, props),
}).use(inertia)
})
}
export function withVite(pages: Record<string, any>, name: string) {
// eslint-disable-next-line no-restricted-syntax
for (const path in pages) {
if (path.endsWith(`${name.replaceAll('.', '/')}.vue`)) {
return typeof pages[path] === 'function'
? pages[path]()
: pages[path]
}
}
throw new Error(`Page not found: ${name}`)
}
@MuhammedAlkhudiry
Copy link

import { withVite } from '@/scripts/inertia/with-vite'

can you please post the with-vite file?

@innocenzi
Copy link
Author

Sure, I just did

@bedus-creation
Copy link

One question, why we need server.ts, can we exclude server.ts ? like you did here https://gist.github.com/innocenzi/f43e815c1ab9168ce4409c37f2f6ac51 ?

@egyjs
Copy link

egyjs commented Sep 6, 2022

its not working

@RPPLSRF
Copy link

RPPLSRF commented Jan 25, 2023

I still don't understand how this works??? could you go into more details???

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