Edit

Migration to +server

Guide to migrate from vike-photon to +server.js.

vike-photon is deprecated — it has been replaced by +server.

See: Blog > Introducing Universal Deploy.

1. Update dependencies

npm uninstall vike-photon
npm install vike@latest
pnpm remove vike-photon
pnpm add vike@latest
bun remove vike-photon
bun add vike@latest
yarn remove vike-photon
yarn add vike@latest
npm uninstall @photonjs/hono
npm install @vikejs/hono
pnpm remove @photonjs/hono
pnpm add @vikejs/hono
bun remove @photonjs/hono
bun add @vikejs/hono
yarn remove @photonjs/hono
yarn add @vikejs/hono

2. Update vite.config.ts (optional)

If you are using Vercel or Cloudflare, you should now use their Vite plugins instead of Photon plugins.

npm uninstall @photonjs/vercel
npm install vite-plugin-vercel
pnpm remove @photonjs/vercel
pnpm add vite-plugin-vercel
bun remove @photonjs/vercel
bun add vite-plugin-vercel
yarn remove @photonjs/vercel
yarn add vite-plugin-vercel
// vite.config.js
 
import vike from 'vike/plugin'
import { vercel } from 'vite-plugin-vercel/vite'
 
export default {
  plugins: [
    vike(),
    vercel() 
  ]
}
// vite.config.ts
 
import vike from 'vike/plugin'
import { vercel } from 'vite-plugin-vercel/vite'
 
export default {
  plugins: [
    vike(),
    vercel() 
  ]
}

3. Update +config.ts

Remove vike-photon extension and +photon settings.

// pages/+config.js
 
import vikePhoton from 'vike-photon/config'
 
export default {
  extends: [
    vikePhoton 
  ],
  photon: {
    server: 'server/index.js'
  } 
}
// pages/+config.ts
 
import type { Config } from 'vike/types'
import vikePhoton from 'vike-photon/config'
 
export default {
  extends: [
    vikePhoton 
  ],
  photon: { 
    server: 'server/index.ts'
  } 
} satisfies Config

If you used the isr or edge settings, they now live at +vercel.{isr,edge}:

// pages/+config.js
 
export default {
  // ...
  isr: { expiration: 30 }, 
  edge: true, 
  vercel: {
    isr: { expiration: 30 }, 
    edge: true
  }
}
// pages/+config.ts
 
export default {
  // ...
  isr: { expiration: 30 }, 
  edge: true, 
  vercel: {
    isr: { expiration: 30 }, 
    edge: true
  }
}

4. Move server entry to +server.ts

Rename your server entry to +server.js (we recommend to move it at your root directory), and use the standard syntax export default { fetch }.

// server/index.js
// +server.js ////
import { Hono } from 'hono'
import { apply, serve } from '@photonjs/hono'
import vike from '@vikejs/hono'
 
const app = new Hono()
apply(app) 
vike(app) 
 
export default serve(app) 
export default {
  fetch: app.fetch 
} 
// server/index.ts
// +server.ts
 
import type { Server } from 'vike/types'
import { Hono } from 'hono'
import { apply, serve } from '@photonjs/hono'
import vike from '@vikejs/hono'
 
const app = new Hono()
apply(app) 
vike(app) 
 
export default serve(app) 
export default { 
  fetch: app.fetch 
} satisfies Server

If you weren't using a server entry, enable Vike's built-in server instead of creating +server.js:

// pages/+config.js
 
export default {
  // ...
  server: true
}
// pages/+config.ts
 
export default {
  // ...
  server: true, 
}

See also: +server: true.

5. serve() options

Most serve() options have their equivalent, see Integration > +server > Settings.

⚠️

Previously, serve() options applied to both the development and production server. Now, those options only apply to the production server.

If you need the equivalent options for the dev server, use Vite's server settings.

🚧 Server settings are now separate because values usually differ between dev and prod. If you have a use case where settings share the same value in dev and prod, then reach out and we'll create server settings that apply to both dev an prod.

Note that createServer is now built-in and can safely be removed.

Advanced serverOptions should now be passed to prod.node, prod.bun or prod.deno, see srvx > Runtime Specific Options.

6. +photon options

Remove all photon options and replace them with the following.

// pages/+config.js
 
export default {
  photon: {
    // ...
  } 
}
// pages/+config.ts
 
import type { Config } from 'vike/types'
 
export default {
  photon: { 
    // ...
  } 
} satisfies Config

photon.standalone

Replace with standaloner:

npm install standaloner
pnpm add standaloner
bun add standaloner
yarn add standaloner
// vite.config.js
 
import { defineConfig } from 'vite'
import standaloner from 'standaloner/vite'
 
export default defineConfig({
  plugins: [
    standaloner() 
  ]
})
// vite.config.ts
 
import { defineConfig } from 'vite'
import standaloner from 'standaloner/vite'
 
export default defineConfig({
  plugins: [
    standaloner() 
  ]
});

photon.compress

Replace with compress:

npm install @universal-middleware/compress
pnpm add @universal-middleware/compress
bun add @universal-middleware/compress
yarn add @universal-middleware/compress
// +server.js
 
import { Hono } from 'hono'
import vike from '@vikejs/hono'
import compress from '@universal-middleware/compress'
 
const app = new Hono()
vike(app) 
// Add universal middlewares here (same for Express.js, Fastify, ...)
vike(app, [compress()]) 
// +server.ts
 
import { Hono } from 'hono'
import vike from '@vikejs/hono'
import compress from '@universal-middleware/compress'
 
const app = new Hono()
vike(app) 
// Add universal middlewares here (same for Express.js, Fastify, ...)
vike(app, [compress()]) 

photon.static

Replace with the prod.static setting in +server.js:

// +server.js
 
export default {
  // ...
  prod: {
    // Serve static files automatically
    static: true, // Default value
    // Can be disabled:
    static: false, 
    // Or serve from a custom folder:
    static: './public'
  }
}
// +server.ts
 
export default {
  // ...
  prod: {
    // Serve static files automatically
    static: true, // Default value
    // Can be disabled:
    static: false, 
    // Or serve from a custom folder:
    static: './public'
  }
}

7. Typescript (optional)

If you use pageContext.runtime and TypeScript:

 
declare global {
  namespace Vike {
    interface Photon {  
    interface Server { 
      // Pick your server (for correct pageContext.runtime type)
      server: 'hono' // 'express' | 'fastify' | 'hattip' | 'srvx' | 'elysia' | 'h3'
    }
  }
}

See also