Skip to content

Commit

Permalink
Export new middlewares and document them
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiodxa committed Jul 12, 2023
1 parent d197a1d commit 517b2b0
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 45 deletions.
116 changes: 112 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Remix adapter for Hono

[Remix](https://remix.run) is a web framework for building web applications,
which can run on the Edge.
> [Remix](https://remix.run) is a web framework for building web applications,
> which can run on the Edge.
[Hono](https://hono.dev) is a small and ultrafast web framework for the Edges.
> [Hono](https://hono.dev) is a small and ultrafast web framework for the Edges.
This adapter allows you to use Hono with Remix, so you can use the best of each
one.
Expand All @@ -26,7 +26,7 @@ import { logDevReady } from "@remix-run/cloudflare";
import * as build from "@remix-run/dev/server-build";
import { Hono } from "hono";
import { handle } from "hono/cloudflare-pages";
import { remix } from "remix-hono";
import { remix } from "remix-hono/cloudflare";

if (process.env.NODE_ENV === "development") logDevReady(build);

Expand Down Expand Up @@ -70,6 +70,114 @@ server.use("*", remix(options));
With just that, your app will now have basic auth protection, which can work
great of preview applications.

## Session Middleware

Additionally to the `remix` Hono middleware, there are other three middlewares
to work with Remix sessions.

Because Remix sessions typically use a secret coming from the environment you
will need access to Hono `ctx.env` to use them. If you're using the Worker KV
session storage you will also need to pass the KV binding to the middleware.

You can use the different middlewares included in this package to do that:

```ts
import { session } from "remix-hono/session";
import { createWorkerKVSessionStorage } from "@remix-run/cloudflare";

server.use(
"*",
session({
autoCommit: true,
createSessionStorage(context) {
return createWorkersKVSessionStorage({
kv: context.env.MY_KV_BINDING,
cookie: {
name: "session",
httpOnly: true,
secrets: [context.SESSION_SECRET],
},
});
},
}),
);
```

Now, setup the Remix middleware after your session middleware and use the
helpers `getSessionStorage` and `getSession` to access the SessionStorage and
Session objects.

> **Note** The Session object will only be defined if autoCommit was set as true
> in the session middleware options. If you set it to false, you will need to
> call `sessionStorage.getSession()` manually.
```ts
import { getSessionStorage, getSession } from "remix-hono/session";
server.use(
"*",
remix<ContextEnv>({
build,
mode: process.env.NODE_ENV as "development" | "production",
// getLoadContext is optional, the default function is the same as here
getLoadContext(ctx) {
let sessionStorage = getSessionStorage(ctx);
let session = getSession(ctx);

// Return them here to access them in your loaders and actions
return { ...ctx.env, sessionStorage, session };
},
}),
);
```

The `session` middleware is generic and lets you use any session storage
mechanism. If you want to use the Worker KV session storage you can use the
`workerKVSession` middleware instead.

```ts
import { workerKVSession } from "remix-hono/session/worker-kv";

server.use(
"*",
workerKVSession({
autoCommit: true, // same as in the session middleware
cookie: {
name: "session", // all cookie options as in createWorkerKVSessionStorage
// In this function, you can access context.env to get the session secret
secrets(context) {
return [context.env.SECRET];
},
},
// The name of the binding using for the KVNamespace
binding: "KV_BINDING",
}),
);
```

If you want to use the cookie session storage, you can use the `cookieSession`
middleware instead.

```ts
import { cookieSession } from "remix-hono/session/cookie";

server.use(
"*",
cookieSession({
autoCommit: true, // same as in the session middleware
cookie: {
name: "session", // all cookie options as in createCookieSessionStorage
// In this function, you can access context.env to get the session secret
secrets(context) {
return [context.env.SECRET];
},
},
}),
);
```

In both `workerKVSession` and `cookieSession` you use `getSession` and
`getSessionStorage` imported from `remix-hono/session`

## Author

- [Sergio Xalambrí](https://sergiodxa.com)
Expand Down
16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,18 @@
"types": "./build/cloudflare.d.ts",
"default": "./build/cloudflare.js"
},
"./cookie-session": {
"types": "./build/cookie-session.d.ts",
"default": "./build/cookie-session.js"
},
"./kv-session": {
"types": "./build/kv-session.d.ts",
"default": "./build/kv-session.js"
},
"./session": {
"types": "./build/session.d.ts",
"default": "./build/session.js"
},
"./session/cookie": {
"types": "./build/cookie-session.d.ts",
"default": "./build/cookie-session.js"
},
"./session/worker-kv": {
"types": "./build/worker-kv-session.d.ts",
"default": "./build/worker-kv-session.js"
},
"./package.json": "./package.json"
},
"scripts": {
Expand Down
17 changes: 2 additions & 15 deletions src/middlewares/cookie-session.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { Context, MiddlewareHandler } from "hono";

import {
CookieOptions,
SessionData,
createCookieSessionStorage,
} from "@remix-run/cloudflare";
import { Context, Hono, MiddlewareHandler } from "hono";

import { session } from "./session";

Expand Down Expand Up @@ -47,17 +48,3 @@ export function kvSession<
},
});
}

new Hono().use(
"*",
kvSession({
autoCommit: true,
cookie: {
name: "__session",
httpOnly: true,
secrets(context) {
return [context.env.SECRET];
},
},
}),
);
8 changes: 6 additions & 2 deletions src/middlewares/session.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { Session, SessionData, SessionStorage } from "@remix-run/cloudflare";
import { Context, Env, Input, MiddlewareHandler } from "hono";
import type {
Session,
SessionData,
SessionStorage,
} from "@remix-run/cloudflare";
import type { Context, Env, Input, MiddlewareHandler } from "hono";

const sessionStorageSymbol = Symbol();
const sessionSymbol = Symbol();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { Context, MiddlewareHandler } from "hono";

import {
CookieOptions,
SessionData,
createWorkersKVSessionStorage,
} from "@remix-run/cloudflare";
import { Context, Hono, MiddlewareHandler } from "hono";

import { session } from "./session";

Expand All @@ -15,7 +16,7 @@ type BindingsObject<KV extends string, Secret extends string> = {
[K in KV | Secret]: K extends KV ? KVNamespace : string;
};

export function kvSession<
export function workerKVSession<
KVBinding extends string,
SecretBinding extends string,
Data = SessionData,
Expand Down Expand Up @@ -54,17 +55,3 @@ export function kvSession<
},
});
}

new Hono().use(
"*",
kvSession({
autoCommit: true,
cookie: {
name: "session",
secrets(context) {
return [context.env.SECRET];
},
},
binding: "KV_BINDING",
}),
);

0 comments on commit 517b2b0

Please sign in to comment.