Skip to content

Commit 92e9aac

Browse files
bcbogdanporcellus
andauthored
feat: Next.js SSR Improvements (#877)
* improv: add an improved way of refreshing the session during SSR Update the function and add types Add more info about the proposal Account for pages directory in the function implementation Update types and clean things up Add comments Add nextjs init function Add the jose library Fix refreshing and add example Fix build and token config Fix payload processing Load config fron env variables Add a redirect location during refresh Refresh token from middleware Move everything in the library Rename files and update function singatures Use the correct refresh path Use normal responses instead of nextresponse Use normal request instead of nextrequest Cleanup implementation Revoke session inside the middleware Code review fixes Add tests for getSSRSession Add tests for middleware * check server actions * Add authenticate HOF for server actions :q * Update examples * Code review fixes * fix: Fix token management during ssr in header based setups * test: Add nextjs e2e tests * test: Extend e2e tests * fix: Linting fixes * chore: Update changelog * fix: Move jwtVerify to a separate file and remove jose * fix: Fix prune errors * ci: Update core docker image * chore: Remove comments * fix: Fix exports to make tests work * test: Update CI testing * fix: Code review fixes * fix: Use the correct path for the refresh token cookie * fix: Update naming to underline lack of claim validation * fix: Include requireAuth in the getServerActionSession function * test: Fix flaky tests * fix: Fix function names * fix: review fixes * chore: update size limit --------- Co-authored-by: Mihaly Lengyel <[email protected]>
1 parent b337b23 commit 92e9aac

File tree

120 files changed

+28331
-25605
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

120 files changed

+28331
-25605
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
77

8-
## [unreleased]
8+
## [0.51]
9+
10+
- Add utilities for session management during server side rendering
911

1012
## [0.50] - 2025-08-15
1113

compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
services:
22
core:
33
# Uses `$SUPERTOKENS_CORE_VERSION` when available, else latest
4-
image: supertokens/supertokens-core:dev-branch-${SUPERTOKENS_CORE_VERSION:-master}
4+
image: supertokens/supertokens-dev-postgresql:${SUPERTOKENS_CORE_VERSION:-master}
55
ports:
66
# Uses `$SUPERTOKENS_CORE_PORT` when available, else 3567 for local port
77
- ${SUPERTOKENS_CORE_PORT:-3567}:3567

examples/for-tests-nextjs/.env

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
EXT_PUBLIC_SUPERTOKENS_APP_NAME=test
2+
NEXT_PUBLIC_SUPERTOKENS_API_DOMAIN=http://localhost:3031
3+
NEXT_PUBLIC_SUPERTOKENS_WEBSITE_DOMAIN=http://localhost:3031
4+
NEXT_PUBLIC_SUPERTOKENS_API_BASE_PATH=/api/auth
5+
NEXT_PUBLIC_SUPERTOKENS_WEBSITE_BASE_PATH=/auth
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "next/core-web-vitals"
3+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# next.js
12+
/.next/
13+
/out/
14+
15+
# production
16+
/build
17+
18+
# misc
19+
.DS_Store
20+
*.pem
21+
22+
# debug
23+
npm-debug.log*
24+
yarn-debug.log*
25+
yarn-error.log*
26+
27+
# local env files
28+
.env*.local
29+
30+
# vercel
31+
.vercel
32+
33+
# typescript
34+
*.tsbuildinfo
35+
next-env.d.ts
36+
37+
# VSCode
38+
.vscode
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# SuperTokens App with Next.js app directory
2+
3+
This is a simple application that is protected by SuperTokens. This app uses the Next.js app directory.
4+
5+
## How to use
6+
7+
### Using `create-next-app`
8+
9+
- Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example:
10+
11+
```bash
12+
npx create-next-app --example with-supertokens with-supertokens-app
13+
```
14+
15+
```bash
16+
yarn create next-app --example with-supertokens with-supertokens-app
17+
```
18+
19+
```bash
20+
pnpm create next-app --example with-supertokens with-supertokens-app
21+
```
22+
23+
- Run `yarn install`
24+
25+
- Run `npm run dev` to start the application on `http://localhost:3000`.
26+
27+
### Using `create-supertokens-app`
28+
29+
- Run the following command
30+
31+
```bash
32+
npx create-supertokens-app@latest --frontend=next
33+
```
34+
35+
- Select the option to use the app directory
36+
37+
Follow the instructions after `create-supertokens-app` has finished
38+
39+
## Notes
40+
41+
- To know more about how this app works and to learn how to customise it based on your use cases refer to the [SuperTokens Documentation](https://supertokens.com/docs/guides)
42+
- We have provided development OAuth keys for the various built-in third party providers in the `/app/config/backend.ts` file. Feel free to use them for development purposes, but **please create your own keys for production use**.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"use server";
2+
3+
import { cookies } from "next/headers";
4+
import { getServerActionSessionWithoutClaimValidation, init } from "supertokens-auth-react/nextjs/ssr";
5+
import { ssrConfig } from "../config/ssr";
6+
7+
init(ssrConfig());
8+
9+
export async function protectedAction() {
10+
const cookiesStore = await cookies();
11+
const { status, session } = await getServerActionSessionWithoutClaimValidation(cookiesStore);
12+
13+
if (status !== "valid") {
14+
return { status, userId: undefined };
15+
}
16+
17+
return { status, userId: session.userId };
18+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
"use server";
2+
3+
import { cookies } from "next/headers";
4+
import { ssrConfig } from "../config/ssr";
5+
6+
export async function unprotectedAction() {
7+
return Promise.resolve("success");
8+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { getAppDirRequestHandler } from "supertokens-node/nextjs";
2+
import Session, { refreshSessionWithoutRequestResponse } from "supertokens-node/recipe/session";
3+
import { NextRequest, NextResponse } from "next/server";
4+
import { ensureSuperTokensInit } from "../../../config/backend";
5+
import { cookies } from "next/headers";
6+
7+
ensureSuperTokensInit();
8+
9+
const handleCall = getAppDirRequestHandler();
10+
11+
export async function GET(request: NextRequest) {
12+
const res = await handleCall(request);
13+
if (!res.headers.has("Cache-Control")) {
14+
// This is needed for production deployments with Vercel
15+
res.headers.set("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate");
16+
}
17+
return res;
18+
}
19+
20+
export async function POST(request: NextRequest) {
21+
return handleCall(request);
22+
}
23+
24+
export async function DELETE(request: NextRequest) {
25+
return handleCall(request);
26+
}
27+
28+
export async function PUT(request: NextRequest) {
29+
return handleCall(request);
30+
}
31+
32+
export async function PATCH(request: NextRequest) {
33+
return handleCall(request);
34+
}
35+
36+
export async function HEAD(request: NextRequest) {
37+
return handleCall(request);
38+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { getCoreUrl } from "@/app/config/backend";
2+
import { NextResponse, NextRequest } from "next/server";
3+
import { withSession } from "supertokens-node/nextjs";
4+
5+
export async function POST(request: NextRequest) {
6+
const updatePayload: Record<string, unknown> = {};
7+
const coreUrl = getCoreUrl();
8+
9+
await fetch(`${coreUrl}/recipe/multitenancy/connectionuridomain/v2`, {
10+
method: "PUT",
11+
body: JSON.stringify(updatePayload),
12+
headers: {
13+
"Content-Type": "application/json",
14+
},
15+
});
16+
17+
return NextResponse.json({});
18+
}

0 commit comments

Comments
 (0)