Files
agent/.agent/skills/tech-stack/elysiajs/integrations/nextjs.md

2.1 KiB

Next.js Integration

What It Is

Run Elysia on Next.js App Router.

Setup

  1. Create app/api/[[...slugs]]/route.ts
  2. Define Elysia + export handlers:
// app/api/[[...slugs]]/route.ts
import { Elysia, t } from 'elysia'

const app = new Elysia({ prefix: '/api' })
  .get('/', 'Hello Nextjs')
  .post('/', ({ body }) => body, {
    body: t.Object({ name: t.String() })
  })

export const GET = app.fetch
export const POST = app.fetch

WinterCG compliance - works as normal Next.js API route.

Prefix for Non-Root

If placed in app/user/[[...slugs]]/route.ts, set prefix:

const app = new Elysia({ prefix: '/user' })
  .get('/', 'Hello Nextjs')

export const GET = app.fetch
export const POST = app.fetch

Eden (End-to-End Type Safety)

Isomorphic fetch pattern:

  • Server: Direct calls (no network)
  • Client: Network calls
  1. Export type:
// app/api/[[...slugs]]/route.ts
export const app = new Elysia({ prefix: '/api' })
  .get('/', 'Hello Nextjs')
  .post('/user', ({ body }) => body, {
    body: treaty.schema('User', { name: 'string' })
  })

export type app = typeof app

export const GET = app.fetch
export const POST = app.fetch
  1. Create client:
// lib/eden.ts
import { treaty } from '@elysiajs/eden'
import type { app } from '../app/api/[[...slugs]]/route'

export const api =
  typeof process !== 'undefined'
    ? treaty(app).api
    : treaty<typeof app>('localhost:3000').api

Use typeof process not typeof window (window undefined at build time → hydration error).

  1. Use in components:
// app/page.tsx
import { api } from '../lib/eden'

export default async function Page() {
  const message = await api.get()
  return <h1>Hello, {message}</h1>
}

Works with server/client components + ISR.

React Query

import { useQuery } from '@tanstack/react-query'

function App() {
  const { data: response } = useQuery({
    queryKey: ['get'],
    queryFn: () => getTreaty().get()
  })
  
  return response?.data
}

Works with all React Query features.

pnpm

Manual install:

pnpm add @sinclair/typebox openapi-types