Skip to content

Commit

Permalink
docs(Examples): Add examples for Pages Router (#631)
Browse files Browse the repository at this point in the history
  • Loading branch information
vvo committed Nov 21, 2023
1 parent 52959c4 commit 68d308e
Show file tree
Hide file tree
Showing 41 changed files with 1,055 additions and 158 deletions.
13 changes: 7 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
<small><i>Psst: This README is for `iron-session` v8 which brings full Next.js App Router compatibility. The previous documentation is [here](https://github.com/vvo/iron-session/tree/v6)</i></small>
<small><i>Psst: This README is for `iron-session` v8 which brings full Next.js App Router compatibility. The previous documentation is [here](https://github.com/vvo/iron-session/tree/v6)</i></small>.

# iron-session [![GitHub license](https://img.shields.io/github/license/vvo/iron-session?style=flat)](https://github.com/vvo/iron-session/blob/master/LICENSE) [![npm](https://img.shields.io/npm/v/iron-session)](https://www.npmjs.com/package/iron-session) [![Downloads](https://img.shields.io/npm/dm/next-iron-session.svg)](http://npm-stat.com/charts.html?package=iron-session)
---

**`iron-session` is a secure, stateless, and cookie-based session library for JavaScript.**
# iron-session ![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/vvo/iron-session/ci.yaml) [![GitHub license](https://img.shields.io/github/license/vvo/iron-session?style=flat)](https://github.com/vvo/iron-session/blob/master/LICENSE) [![npm](https://img.shields.io/npm/v/iron-session)](https://www.npmjs.com/package/iron-session) [![Downloads](https://img.shields.io/npm/dm/next-iron-session.svg)](http://npm-stat.com/charts.html?package=iron-session) ![npm package minimized gzipped size (select exports)](https://img.shields.io/bundlejs/size/iron-session?exports=getIronSession)

<p align="center">Online demo: <a href="https://get-iron-session.vercel.app/">https://get-iron-session.vercel.app</a> 👀</p>
**`iron-session` is a secure, stateless, and cookie-based session library for JavaScript.**

The session data is stored in signed and encrypted cookies which are decoded by your server code in a stateless fashion (= no network involved). This is the same technique used by frameworks like
[Ruby On Rails](https://guides.rubyonrails.org/security.html#session-storage).

<p align="center"><i>⭐️ Featured in the <a href="https://nextjs.org/docs/authentication">Next.js documentation</a></i></p>
<p align="center"><i>Online demo and examples: <a href="https://get-iron-session.vercel.app/">https://get-iron-session.vercel.app</a></i> 👀 <br/>
<i>Featured in the <a href="https://nextjs.org/docs/authentication">Next.js documentation</a></i> ⭐️</p>

## Table of Contents

Expand Down Expand Up @@ -145,7 +146,7 @@ await session.save()
Destroys the session. This is a synchronous operation as it only removes the cookie. It must be done before headers are sent to the client.

```ts
await session.destroy()
session.destroy()
```

### `sealData(data: unknown, { password, ttl }): Promise<string>`
Expand Down
2 changes: 1 addition & 1 deletion examples/next/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@
"eslint-config-next": "14.0.3",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"typescript": "^5"
"typescript": "^5.3.2"
}
}
Binary file added examples/next/public/background.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions examples/next/public/github-mark-white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
22 changes: 22 additions & 0 deletions examples/next/src/app/GitHubLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Image from "next/image";

export default function GitHubLogo() {
return (
<>
<Image
src="/github-mark.svg"
alt="GitHub Logo"
width={20}
height={20}
className="dark:hidden"
/>
<Image
src="/github-mark-white.svg"
alt="GitHub Logo"
width={20}
height={20}
className="hidden dark:block"
/>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function LoginForm() {
className={css.form}
>
<label className="block text-lg">
<span className="text-gray-700">Username</span>
<span className={css.label}>Username</span>
<input
type="text"
name="username"
Expand All @@ -69,7 +69,7 @@ function LogoutButton() {
return (
<p>
<a
href="/app-router-client-component-redirect-route-handler-fetch/logout"
href="/app-router-client-component-redirect-route-handler-fetch/session?action=logout"
className={css.button}
>
Logout
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as css from "@/app/css";
import { Metadata } from "next";
import { Form } from "./form";
import { Title } from "../title";
import { GetTheCode } from "../get-the-code";
import { GetTheCode } from "../../get-the-code";

export const metadata: Metadata = {
title:
Expand All @@ -21,7 +21,7 @@ export default function AppRouterRedirect() {
action.
</p>

<div className="grid grid-cols-1 gap-4 p-10 border border-gray-500 rounded-md max-w-xl">
<div className="grid grid-cols-1 gap-4 p-10 border border-slate-500 rounded-md max-w-xl">
<Form />
</div>

Expand All @@ -40,20 +40,21 @@ export default function AppRouterRedirect() {
function HowItWorks() {
return (
<details className="max-w-2xl space-y-4">
<summary className="cursor-pointer text-gray-700">How it works</summary>
<summary className="cursor-pointer">How it works</summary>

<ol className="list-decimal list-inside">
<li>
The form is submitted to
/app-router-client-component-redirect-route-handler-fetch/session
(route handler) via a POST call (non-fetch). The route handler sets
the session data and redirects back to /app-router (this page).
/app-router-client-component-redirect-route-handler-fetch/session (API
route) via a POST call (non-fetch). The API route sets the session
data and redirects back to
/app-router-client-component-redirect-route-handler-fetch (this page).
</li>
<li>
The page gets the session data via a fetch call to
/app-router-client-component-redirect-route-handler-fetch/session
(route handler). The route handler either return the session data
(logged in) or a default session (not logged in).
/app-router-client-component-redirect-route-handler-fetch/session (API
route). The API route either return the session data (logged in) or a
default session (not logged in).
</li>
<li>
The logout is a regular link navigating to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@ import { redirect } from "next/navigation";
import { sleep, SessionData } from "../lib";

// /app-router-client-component-redirect-route-handler-fetch/session
export async function POST(
request: NextRequest,
{ params }: { params: { action: string } },
) {
if (params.action !== "session") {
return new Response("Unknown path", { status: 404 });
}

export async function POST(request: NextRequest) {
const session = await getIronSession<SessionData>(cookies(), sessionOptions);

const formData = await request.formData();
Expand All @@ -34,20 +27,15 @@ export async function POST(
}

// /app-router-client-component-redirect-route-handler-fetch/session
// /app-router-client-component-redirect-route-handler-fetch/logout
export async function GET(
_request: NextRequest,
{ params }: { params: { action: string } },
) {
if (params.action !== "session" && params.action !== "logout") {
return new Response("Unknown path", { status: 404 });
}

// /app-router-client-component-redirect-route-handler-fetch/session?action=logout
export async function GET(request: NextRequest) {
const session = await getIronSession<SessionData>(cookies(), sessionOptions);

// /app-router-client-component-redirect-route-handler-fetch/logout
if (params.action === "logout") {
await session.destroy();
console.log(new URL(request.url).searchParams);
const action = new URL(request.url).searchParams.get("action");
// /app-router-client-component-redirect-route-handler-fetch/session?action=logout
if (action === "logout") {
session.destroy();
return redirect(
"/app-router-client-component-redirect-route-handler-fetch",
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function LoginForm() {
className={css.form}
>
<label className="block text-lg">
<span className="text-gray-700">Username</span>
<span className={css.label}>Username</span>
<input
type="text"
name="username"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import * as css from "@/app/css";
import { Metadata } from "next";
import { Form } from "./form";
import { Title } from "@/app/title";
import { GetTheCode } from "../get-the-code";
import { GetTheCode } from "../../get-the-code";

export const metadata: Metadata = {
title: "🛠 iron-session examples: Client components, route handlers and SWR",
};

export default function AppRouterRedirect() {
export default function AppRouterSWR() {
return (
<main className="p-10 space-y-5">
<Title
Expand All @@ -34,9 +34,9 @@ export default function AppRouterRedirect() {
SWR automatically.
</p>

<div className="grid grid-cols-1 gap-4 p-10 border border-gray-500 rounded-md max-w-xl">
<div className="grid grid-cols-1 gap-4 p-10 border border-slate-500 rounded-md max-w-xl">
<Form />
<div className="text-gray-700 space-y-2">
<div className="space-y-2">
<hr />
<p>
The following pages are protected and will redirect back here if
Expand Down Expand Up @@ -91,7 +91,7 @@ export default function AppRouterRedirect() {
function HowItWorks() {
return (
<details className="max-w-2xl space-y-4">
<summary className="cursor-pointer text-gray-700">How it works</summary>
<summary className="cursor-pointer">How it works</summary>

<ol className="list-decimal list-inside">
<li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function Content() {
This page is protected and can only be accessed if you are logged in.
Otherwise you will be redirected to the login page.
</p>
<p>The check is done via a fetch call on the client.</p>
<p>The check is done via a fetch call on the client using SWR.</p>
<p>
One benefit of using{" "}
<a href="https://swr.vercel.app" target="_blank" className={css.link}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ export async function GET() {
export async function DELETE() {
const session = await getIronSession<SessionData>(cookies(), sessionOptions);

// /app-router-client-component-route-handler-swr/logout
await session.destroy();
session.destroy();

return Response.json(defaultSession);
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export async function logout() {

// false => no db call for logout
const session = await getSession(false);
await session.destroy();
session.destroy();
revalidatePath("/app-router-server-component-and-action");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function LoginForm() {
return (
<form action={login} className={css.form}>
<label className="block text-lg">
<span className="text-gray-700">Username</span>
<span className={css.label}>Username</span>
<Input />
</label>
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Form } from "./form";
import { Suspense } from "react";
import * as css from "@/app/css";
import { Title } from "../title";
import { GetTheCode } from "../get-the-code";
import { GetTheCode } from "../../get-the-code";

export const metadata: Metadata = {
title: "🛠 iron-session examples: Server components, and server actions",
Expand All @@ -21,7 +21,7 @@ export default async function AppRouter() {
action.
</p>

<div className="grid grid-cols-1 gap-4 p-10 border border-gray-500 rounded-md max-w-xl">
<div className="grid grid-cols-1 gap-4 p-10 border border-slate-500 rounded-md max-w-xl">
<Suspense fallback={<p className="text-lg">Loading...</p>}>
<Form />
</Suspense>
Expand All @@ -42,7 +42,7 @@ export default async function AppRouter() {
function HowItWorks() {
return (
<details className="max-w-2xl space-y-4">
<summary className="cursor-pointer text-gray-700">How it works</summary>
<summary className="cursor-pointer">How it works</summary>

<ol className="list-decimal list-inside">
<li>During login, the page uses a server action.</li>
Expand Down
9 changes: 6 additions & 3 deletions examples/next/src/app/css.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
export const button =
"hover:bg-gray-200 text-black border border-black py-2 px-4 rounded focus:outline-2 cursor-pointer";
"hover:bg-slate-200 dark:hover:bg-slate-600 text-slate-900 dark:text-white border border-text-slate-900 dark:border-text-white py-2 px-4 rounded focus:outline-2 cursor-pointer";

export const form = "max-w-md grid grid-cols-1 gap-6";

export const label = "text-slate-700 dark:text-slate-300";

export const input =
"mt-1 block w-full disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500";
"mt-1 block w-full disabled:cursor-not-allowed disabled:bg-slate-50 disabled:text-slate-500 dark:text-slate-900";

export const link = "text-indigo-500 underline hover:no-underline";
export const link =
"text-indigo-500 dark:text-indigo-400 underline hover:no-underline";
2 changes: 1 addition & 1 deletion examples/next/src/app/fathom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function TrackPageView() {
if (!pathname) return;

trackPageview({
url: pathname + searchParams.toString(),
url: pathname + searchParams?.toString() ?? "",
referrer: document.referrer,
});
}, [pathname, searchParams]);
Expand Down
4 changes: 4 additions & 0 deletions examples/next/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

body {
@apply bg-slate-50 dark:bg-slate-800 text-slate-900 dark:text-white;
}
2 changes: 1 addition & 1 deletion examples/next/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default function RootLayout({
}) {
return (
<html lang="en">
<body className={`${inter.className} bg-gray-50`}>
<body className={inter.className}>
<Fathom />
{children}
</body>
Expand Down
Loading

0 comments on commit 68d308e

Please sign in to comment.