# Hono (/docs/examples/hono)



This example runs a server side A/B test on a [Hono](https://hono.dev/) server using the [`ImproveServerSDK`](/docs/sdk/javascript#server) directly. Unlike the [Next.js example](/docs/examples/nextjs) (where the middleware handles cookies for you), here you manage the visitor and test cookies yourself, which makes it a good reference for any server framework that is not Next.js.

## Install [#install]

```bash
npm i @obelism/improve-sdk hono
```

## Handler [#handler]

The flow on each request is:

1. [`fetchConfig`](/docs/sdk/javascript#fetchconfig) to load the datafile.
2. Read the visitor id and test value from cookies, using [`getVisitorCookieName`](/docs/sdk/javascript#getvisitorcookiename) for the cookie name.
3. Validate those cookie values with `validateVisitorId` and [`validateTestValue`](/docs/sdk/javascript#validatetestvalue); fall back to [`generateVisitorId`](/docs/sdk/javascript#generatevisitorid) and [`getTestValue`](/docs/sdk/javascript#gettestvalue) when they are missing or invalid.
4. Re-store both values in cookies so the visitor keeps the same variant on future visits.

```ts title="src/index.ts"
import { ImproveServerSDK } from '@obelism/improve-sdk/server'
import { Hono } from 'hono'
import { getCookie, setCookie } from 'hono/cookie'

const app = new Hono()

const improveSdk = new ImproveServerSDK({
	organizationId: 'org_MJFL46Z0WXGQ5OHW1ZXSM3Q88S',
	environment: 'staging',
	token: 'xxxx-xxxx-xxxx-xxxx',
})

const AB_TEST_SLUG = 'startpage-visual'

app.get('/', async (c) => {
	//? Get config from Improve
	await improveSdk.fetchConfig()

	//? Get values from cookie for a consistent browsing experience for users
	const visitorCookieName = improveSdk.getVisitorCookieName()
	const visitorIdCookie = getCookie(c, visitorCookieName)
	const testCookieValue = getCookie(c, AB_TEST_SLUG)

	//? Validate if the cookie values are valid
	const validCookieVisitorId =
		visitorIdCookie && improveSdk.validateVisitorId(visitorIdCookie)
	const validCookieValue =
		testCookieValue &&
		improveSdk.validateTestValue(AB_TEST_SLUG, testCookieValue)

	const visitorId = validCookieVisitorId
		? visitorIdCookie
		: improveSdk.generateVisitorId()

	const testValue = validCookieValue
		? testCookieValue
		: improveSdk.getTestValue(
				AB_TEST_SLUG,
				visitorId,
				c.req.header('User-Agent') || '',
			)

	//? Re-store values in cookies for one week
	setCookie(c, visitorCookieName, visitorId, {
		maxAge: 60 * 60 * 24 * 7,
	})
	setCookie(c, AB_TEST_SLUG, testValue, {
		maxAge: 60 * 60 * 24 * 7,
	})

	return c.text(`AB Test: ${testValue}`)
})

export default app
```

**Note:** the runnable example hardcodes the server `token` for brevity. In your own app load it from an environment variable so it never ends up in version control.

## Source [#source]

<Cards>
  <Card title="View on GitHub" href="https://github.com/Obelism/improve-sdk/tree/main/examples/hono" description="Full source for this example" />

  <Card title="View live demo" href="https://hono.improve.obelism.studio" description="This example deployed and running" />
</Cards>
