Skip to content

April Update

April’s biggest update is server-side rendering.

Nano Kit now has ready-to-use SSR for React apps through @nano_kit/react-ssr, plus Next.js support through @nano_kit/next-router. There is also a lower-level @nano_kit/ssr package for building framework adapters.

The goal is simple: keep application logic in the store layer, run it on the server when needed, dehydrate the result, and hydrate it back on the client without rebuilding the same data flow twice.

For React apps, @nano_kit/react-ssr is the main new package in this update. It gives Nano Kit a ready-to-use SSR setup for Vite + React projects, so the same router, stores, and queries can participate in the server render and then continue on the client.

In practice, the setup starts with the plugin:

import ssr from '@nano_kit/react-ssr/vite-plugin'
export default {
plugins: [
ssr({ index: 'src/index.ts' })
]
}

The index file is the shared app definition used by both the browser bundle and the server renderer:

// src/index.ts
import { asModule, page, layout, loadable } from '@nano_kit/react-router'
import * as Layout from './Layout.jsx'
export const routes = {
home: '/',
about: '/about',
user: '/users/:id'
} as const
export const pages = [
layout(asModule(Layout), [
page('home', loadable(() => import('./pages/Home.jsx'))),
page('about', loadable(() => import('./pages/About.jsx'))),
page('user', loadable(() => import('./pages/User.jsx')))
])
]
declare module '@nano_kit/router' {
interface AppContext {
routes: typeof routes
}
}

The plugin builds browser assets and a server renderer bundle. In development, it handles rendering through Vite, so you can work with SSR without writing a local server first.

For production, it does not generate a complete HTTP server. You bring your own server, choose the runtime and middleware you want, serve dist/client as static assets, and call the generated renderer for application routes.

For example, a small Hono server can look like this:

import { serve } from '@hono/node-server'
import { serveStatic } from '@hono/node-server/serve-static'
import { Hono } from 'hono'
import { renderer } from './dist/renderer/index.js'
const app = new Hono()
app.use(
`${renderer.base.replace(/(.)\/$/, '$1')}*`,
serveStatic({ root: './dist/client' })
)
app.get('*', async (c) => {
const result = await renderer.render(c.req.url)
if (result.redirect) {
return c.redirect(result.redirect, result.statusCode)
}
if (result.html !== null) {
return c.html(result.html, result.statusCode)
}
return c.text('Not Found', result.statusCode)
})
serve({ fetch: app.fetch, port: 5173 })

Under the hood, @nano_kit/react-ssr is built on top of @nano_kit/ssr. That base package is mostly for adapter authors: it provides the shared renderer lifecycle, client readiness helpers, Vite manifest handling, and build plugin pieces.

The router also gained SSR-ready page module hooks.

Page modules can export Stores$ to declare which stores should be dehydrated, and Head$ to declare per-page document metadata.

export function Stores$() {
return [$data]
}
export function Head$() {
return [
title('Home - My App')
]
}

The SSR renderer discovers these hooks automatically. You declare redirects, status codes, page modules, and head metadata close to the route, and the renderer uses them during server render.

SSR support also adds hydration and dehydration tools for application data.

In @nano_kit/store, signals can be marked with hydratable(), dehydrated on the server, and restored on the client.

@nano_kit/query now has SSR-specific settings too. The ssr() setting combines task tracking and cache hydration: queries started during server render are tracked, awaited, dehydrated into the payload, and then reused on the client.

import { client, ssr } from '@nano_kit/query'
export function Client$() {
return client(
ssr()
)
}

After hydration, the browser can start from the server snapshot instead of repeating the same request immediately.

React Server Components and Next.js Support

Section titled “React Server Components and Next.js Support”

RSC runtimes can use server and client helpers from @nano_kit/react:

This update also adds @nano_kit/next-router, a Next.js integration for Nano Kit router.

It works with both App Router and Pages Router:

The broader Next.js guide covers flight dehydration, static dehydration, Pages Router hydration, and when to use each setup.

The best place to see the SSR update in motion is the Rick and Morty Encyclopedia example.

It includes embedded sandboxes and source links for:

  • React SSR with @nano_kit/react-ssr
  • Next.js App Router with @nano_kit/next-router
  • Next.js Pages Router with getServerSideProps dehydration

The example uses the same Nano Kit ideas across each environment: router state, query cache, store hydration, and page-level data declarations.

You can also browse the examples overview for smaller apps, including the Weather App and CV Generator.

If you want to try the April update:

SSR is the main theme of this release, but the important part is not just rendering HTML on the server. The important part is that Nano Kit’s store, query, router, and framework adapters now share one SSR story.