Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/eight-walls-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/express': patch
---

Deprecates `enableHandshake` option in `clerkMiddleware`. This option is unnecessary for API requests since they don't trigger handshake flows. The option will be removed in a future version.
4 changes: 3 additions & 1 deletion integration/presets/express.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { linkPackage } from './utils';
const vite = applicationConfig()
.setName('express-vite')
.useTemplate(templates['express-vite'])
.setEnvFormatter('public', key => `VITE_${key}`)
.addScript('setup', 'pnpm install')
.addScript('dev', 'pnpm dev')
.addScript('build', 'pnpm build')
.addScript('serve', 'pnpm start')
.addDependency('@clerk/express', constants.E2E_CLERK_VERSION || linkPackage('express'));
.addDependency('@clerk/express', constants.E2E_CLERK_VERSION || linkPackage('express'))
.addDependency('@clerk/clerk-js', constants.E2E_CLERK_VERSION || linkPackage('clerk-js'));

export const express = {
vite,
Expand Down
13 changes: 13 additions & 0 deletions integration/templates/express-vite/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + TS + Express</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/client/main.ts"></script>
</body>
</html>
22 changes: 10 additions & 12 deletions integration/templates/express-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,20 @@
"private": true,
"scripts": {
"build": "vite build",
"dev": "PORT=$PORT ts-node src/server/main.ts",
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"dev": "PORT=$PORT tsx src/server/main.ts",
"preview": "vite preview --port $PORT --no-open",
"start": "PORT=$PORT ts-node src/server/main.ts"
"start": "PORT=$PORT NODE_ENV=production tsx src/server/main.ts"
},
"dependencies": {
"dotenv": "^16.4.7",
"ejs": "^3.1.6",
"express": "^4.18.2",
"ts-node": "^10.9.1",
"vite-express": "^0.20.0"
"dotenv": "^17.2.1",
"express": "^5.1.0",
"tsx": "^4.20.3",
"vite-express": "^0.21.1"
},
"devDependencies": {
"@types/express": "^4.17.21",
"@types/node": "^20.9.3",
"typescript": "^5.7.3",
"vite": "^5.0.2"
"@types/express": "^5.0.3",
"@types/node": "^24.2.1",
"typescript": "^5.8.3",
"vite": "^6.3.3"
}
}
26 changes: 26 additions & 0 deletions integration/templates/express-vite/src/client/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Clerk } from '@clerk/clerk-js';

const publishableKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;

document.addEventListener('DOMContentLoaded', async function () {
const clerk = new Clerk(publishableKey);
await clerk.load();

if (clerk.isSignedIn) {
document.getElementById('app')!.innerHTML = `
<div id="user-button"></div>
`;

const userButtonDiv = document.getElementById('user-button');

clerk.mountUserButton(userButtonDiv);
} else {
document.getElementById('app')!.innerHTML = `
<div id="sign-in"></div>
`;

const signInDiv = document.getElementById('sign-in');

clerk.mountSignIn(signInDiv);
}
});
7 changes: 7 additions & 0 deletions integration/templates/express-vite/src/client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Bundler"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
59 changes: 20 additions & 39 deletions integration/templates/express-vite/src/server/main.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,44 @@
// Should be at the top of the file - used to load clerk secret key
import 'dotenv/config';

import { clerkMiddleware } from '@clerk/express';
import { clerkMiddleware, getAuth } from '@clerk/express';
import express from 'express';
import ViteExpress from 'vite-express';

const app = express();

app.use(clerkMiddleware());
app.set('view engine', 'ejs');
app.set('views', 'src/views');
app.use(
clerkMiddleware({
publishableKey: process.env.VITE_CLERK_PUBLISHABLE_KEY,
}),
);

app.get('/api/protected', (req: any, res: any, _next: any) => {
const { userId } = getAuth(req);
if (!userId) {
res.status(401).send('Unauthorized');
return;
}

res.send('Protected API response');
});

const legacyRequireAuth = (req: any, _res: any, next: any) => {
if (!req.auth.userId) {
return next(new Error('Unauthenticated'));
return next(new Error('Unauthorized'));
}

next();
};

app.get('/api/protected', legacyRequireAuth, (_req: any, res: any, _next: any) => {
return res.send('Protected API response');
});

app.get('/sign-in', (_req: any, res: any) => {
return res.render('sign-in.ejs', {
publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
signInUrl: process.env.CLERK_SIGN_IN_URL,
});
});

app.get('/', (_req: any, res: any) => {
return res.render('index.ejs', {
publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
signInUrl: process.env.CLERK_SIGN_IN_URL,
});
});

app.get('/sign-up', (_req: any, res: any) => {
return res.render('sign-up.ejs', {
publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
signUpUrl: process.env.CLERK_SIGN_UP_URL,
});
});

app.get('/protected', (_req: any, res: any) => {
return res.render('protected.ejs', {
publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
signInUrl: process.env.CLERK_SIGN_IN_URL,
signUpUrl: process.env.CLERK_SIGN_UP_URL,
});
app.get('/api/legacy/protected', legacyRequireAuth, (_req: any, res: any, _next: any) => {
res.send('Protected API response');
});

// Handle authentication error, otherwise application will crash
// @ts-ignore
app.use((err, req, res, next) => {
if (err) {
console.error(err);
res.status(401).end();
res.status(401).send('Unauthorized');
return;
}

Expand Down
32 changes: 0 additions & 32 deletions integration/templates/express-vite/src/views/index.ejs

This file was deleted.

32 changes: 0 additions & 32 deletions integration/templates/express-vite/src/views/protected.ejs

This file was deleted.

24 changes: 0 additions & 24 deletions integration/templates/express-vite/src/views/sign-in.ejs

This file was deleted.

24 changes: 0 additions & 24 deletions integration/templates/express-vite/src/views/sign-up.ejs

This file was deleted.

18 changes: 9 additions & 9 deletions integration/templates/express-vite/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"module": "NodeNext",
"lib": ["ESNext", "DOM"],
"moduleResolution": "NodeNext",
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "CommonJS",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true
"esModuleInterop": true,
"noEmit": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"skipLibCheck": true
},
"include": ["src"]
}
4 changes: 0 additions & 4 deletions integration/templates/express-vite/vite.config.ts

This file was deleted.

Loading
Loading