Utility Functions

All functions listed below are exported directly by one.

redirect

A function that takes two arguments: a string path, and a number status.

import { redirect } from 'one'
export function redirectToLogin() {
return redirect('/login')
}

It accepts relative paths by using the getURL helper internally.

On the server (including in loaders) it returns a Response.redirect object. On the client it calls router.navigate and returns void.

getURL

A function that takes no arguments and returns a string of the current URL of the running application on client or server.

For example, in dev-mode by default this would be a string of http://127.0.0.1:8081. In non-development environments you will need to set process.env.ONE_SERVER_URL to your production URL with no trailing /.

isResponse

One uses Request/Response type objects for API routes, but for some environments doing an instanceof Response can fail, isResponse takes any value and returns true if it is a Response-like object. Useful for API utility functions.

href

A simple function allows for creating typed route strings. It's a type-level only check, at runtime it only validates that it is a string.

import { href } from 'one'
const postPageLink = href(`/post/hello-world`) // will type error if invalid Href

setServerData, getServerData

Developing

For improving performance of client hydration on the web, you can pass data from the server to the client. Data must be serializable to JSON.

Here's an example of a simple useFetch:

app/index.tsx

import { setServerData, getServerData } from 'one'
type SafeURLs = `${`https://tamagui.dev` | `http://localhost`}${string}
const useFetch = async (url: SafeURLs) => {
if (process.env.VITE_ENVIRONMENT === 'ssr') {
// on server data must be set during render
setServerData(url, await fetch(url).then(res => res.json()))
}
return getServerData(url)
}
export default async (props) => {
const serverData = await useFetch(props.url)
return <div />
}
// can use it in loaders, too
export const loader = async ({ params }) => {
await doSomething()
setServerData(params.idl, 'data')
return {}
}

setResponseHeaders

Set HTTP response headers from anywhere during server-side rendering - loaders, components, or middleware. Headers are accumulated and merged onto the final response.

import { setResponseHeaders } from 'one'
await setResponseHeaders((headers) => {
headers.set('X-Custom-Header', 'value')
})

The headers parameter is a standard Headers object.

Caching and ISR

Use setResponseHeaders in loaders to enable CDN caching and Incremental Static Regeneration:

app/blog/[slug]+ssr.tsx

import { setResponseHeaders, useLoader } from 'one'
export async function loader({ params }) {
await setResponseHeaders((headers) => {
headers.set('Cache-Control', 'public, s-maxage=3600, stale-while-revalidate=86400')
})
const post = await fetchPost(params.slug)
return { post }
}
export default function BlogPost() {
const { post } = useLoader(loader)
return <article>{post.content}</article>
}

Common cache header patterns:

  • s-maxage=3600 - CDN caches for 1 hour
  • stale-while-revalidate=86400 - Serve stale content while revalidating in background (up to 1 day)
  • max-age=0, must-revalidate - Always revalidate with origin
  • private, no-store - Never cache (for user-specific data)

Note: stale-while-revalidate requires CDN support (Vercel, CloudFront, Fastly). Cloudflare does not currently support it.

Cookies

Set cookies using the standard Set-Cookie header:

app/auth/login+api.ts

import { setResponseHeaders } from 'one'
export async function POST(request: Request) {
const { token } = await authenticateUser(request)
await setResponseHeaders((headers) => {
headers.append('Set-Cookie', `session=${token}; HttpOnly; Secure; SameSite=Strict; Path=/`)
})
return Response.json({ success: true })
}

In Middleware

app/_middleware.ts

import { createMiddleware, setResponseHeaders } from 'one'
export default createMiddleware(({ request }) => {
setResponseHeaders((headers) => {
headers.set('X-Request-Id', crypto.randomUUID())
})
})

Important Notes

  • Only works server-side (SSR routes and loaders)
  • Can be called multiple times - headers are merged
  • Must be called during the request lifecycle (not in event handlers or timeouts)

watchFile

A function that registers a file dependency for hot reload during development. When the file changes, the loader will automatically re-run and refresh data on the client without a full page reload.

app/blog/[slug].tsx

import { watchFile } from 'one'
import { readFile } from 'fs/promises'
export async function loader({ params: { slug } }) {
const filePath = `./content/${slug}.mdx`
watchFile(filePath)
const content = await readFile(filePath, 'utf-8')
return { content }
}
  • No-op in production and on the client
  • Pass the same path you use with fs.readFile or similar
  • See Loaders - Hot Reload for more details

Edit this page on GitHub.