Skip to content

Commit 1ca52bd

Browse files
authored
Merge pull request #4 from aggmoulik/feature/nextjs-13
Feature: Nextjs 13 Examples
2 parents 3ae8c5e + e83a385 commit 1ca52bd

21 files changed

+1528
-0
lines changed

with-nextjs-13/.gitignore

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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+
.env.development.local
30+
.env.test.local
31+
.env.production.local
32+
33+
# vercel
34+
.vercel

with-nextjs-13/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Authorizer + Next.js + Tailwind CSS Example
2+
3+
This example shows how to use [Authorizer](https://authorizer.dev) with Next.js. It follows the steps outlined in the official [Authorizer docs](https://docs.authorizer.dev/).
4+
5+
6+
## Deploy your own
7+
8+
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
9+
10+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/authorizerdev/examples/tree/main/with-nextjs&project-name=authorizer-with-nextjs-example&repository-name=authorizer-with-nextjs-example)

with-nextjs-13/app/error.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
'use client';
2+
3+
import { useEffect } from 'react';
4+
5+
export default function Error({ error, reset }) {
6+
useEffect(() => {
7+
// Log the error to an error reporting service
8+
console.error('error',error);
9+
}, [error]);
10+
11+
return (
12+
<div>
13+
<p>Something went wrong!</p>
14+
<button onClick={() => reset()}>Reset error boundary</button>
15+
</div>
16+
);
17+
}

with-nextjs-13/app/head.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export default function Head() {
2+
return (
3+
<>
4+
<title>Create Next App</title>
5+
<link rel="icon" href="/favicon.ico" />
6+
</>
7+
);
8+
}

with-nextjs-13/app/layout.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use client';
2+
3+
import { AuthorizerProvider } from '@authorizerdev/authorizer-react';
4+
import Nav from '../components/nav';
5+
import authorizerConfig from '../config/authorizer-config';
6+
import '../styles/globals.css';
7+
8+
const onStateChangeCallback = async ({ token }) => {
9+
await fetch(
10+
'/api/session',
11+
{
12+
method: 'POST',
13+
body: JSON.stringify(token),
14+
},
15+
{ cache: 'no-store' }
16+
);
17+
};
18+
19+
export default function RootLayout({ children }) {
20+
return (
21+
<html lang="en">
22+
<AuthorizerProvider
23+
config={authorizerConfig}
24+
onStateChangeCallback={onStateChangeCallback}
25+
>
26+
<body>
27+
<Nav />
28+
<div className="flex flex-col items-center justify-center min-h-screen py-2">
29+
{children}
30+
</div>
31+
<footer className="flex items-center justify-center w-full h-24 border-t">
32+
<a
33+
className="flex items-center justify-center"
34+
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
35+
target="_blank"
36+
rel="noopener noreferrer"
37+
>
38+
Powered by{' '}
39+
<img src="/vercel.svg" alt="Vercel Logo" className="h-4 ml-2" />
40+
</a>
41+
</footer>
42+
</body>
43+
</AuthorizerProvider>
44+
</html>
45+
);
46+
}

with-nextjs-13/app/loading.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use client'
2+
3+
import { useAuthorizer } from '@authorizerdev/authorizer-react';
4+
5+
export default function Loading() {
6+
const { loading } = useAuthorizer();
7+
return loading ? <h1 className="text-2xl">Loading...</h1> : null;
8+
}

with-nextjs-13/app/login/page.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
'use client';
2+
3+
import { useEffect } from 'react';
4+
import { Authorizer, useAuthorizer } from '@authorizerdev/authorizer-react';
5+
import { useRouter } from 'next/navigation';
6+
7+
export default function Login() {
8+
const { token } = useAuthorizer();
9+
const router = useRouter();
10+
useEffect(() => {
11+
if (token) {
12+
router.push('/');
13+
}
14+
}, [token]);
15+
return <Authorizer />;
16+
}

with-nextjs-13/app/page.js

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
export default function Home() {
2+
return (
3+
<main className="flex flex-col items-center justify-center w-full flex-1 px-20 text-center">
4+
<h1 className="text-6xl font-bold">
5+
Welcome to{' '}
6+
<a className="text-blue-600" href="https://nextjs.org">
7+
Next.js!
8+
</a>
9+
</h1>
10+
11+
<p className="mt-3 text-2xl">
12+
Get started by editing{' '}
13+
<code className="p-3 font-mono text-lg bg-gray-100 rounded-md">
14+
pages/index.js
15+
</code>
16+
</p>
17+
18+
<div className="flex flex-wrap items-center justify-around max-w-4xl mt-6 sm:w-full">
19+
<a
20+
href="https://nextjs.org/docs"
21+
className="p-6 mt-6 text-left border w-96 rounded-xl hover:text-blue-600 focus:text-blue-600"
22+
>
23+
<h3 className="text-2xl font-bold">Documentation &rarr;</h3>
24+
<p className="mt-4 text-xl">
25+
Find in-depth information about Next.js features and API.
26+
</p>
27+
</a>
28+
29+
<a
30+
href="https://nextjs.org/learn"
31+
className="p-6 mt-6 text-left border w-96 rounded-xl hover:text-blue-600 focus:text-blue-600"
32+
>
33+
<h3 className="text-2xl font-bold">Learn &rarr;</h3>
34+
<p className="mt-4 text-xl">
35+
Learn about Next.js in an interactive course with quizzes!
36+
</p>
37+
</a>
38+
39+
<a
40+
href="https://github.com/vercel/next.js/tree/master/examples"
41+
className="p-6 mt-6 text-left border w-96 rounded-xl hover:text-blue-600 focus:text-blue-600"
42+
>
43+
<h3 className="text-2xl font-bold">Examples &rarr;</h3>
44+
<p className="mt-4 text-xl">
45+
Discover and deploy boilerplate example Next.js projects.
46+
</p>
47+
</a>
48+
49+
<a
50+
href="https://vercel.com/import?filter=next.js&utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
51+
className="p-6 mt-6 text-left border w-96 rounded-xl hover:text-blue-600 focus:text-blue-600"
52+
>
53+
<h3 className="text-2xl font-bold">Deploy &rarr;</h3>
54+
<p className="mt-4 text-xl">
55+
Instantly deploy your Next.js site to a public URL with Vercel.
56+
</p>
57+
</a>
58+
</div>
59+
</main>
60+
);
61+
}

with-nextjs-13/app/profile/page.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Authorizer } from '@authorizerdev/authorizer-js';
2+
import authorizerConfig from '../../config/authorizer-config';
3+
import { cookies } from 'next/headers';
4+
5+
const getUserData = async () => {
6+
const nextCookies = cookies();
7+
const token = nextCookies.get('authorizer-client-next').value;
8+
const authorizerRef = new Authorizer(authorizerConfig);
9+
10+
return authorizerRef.getProfile({
11+
Authorization: `Bearer ${token}`,
12+
});
13+
};
14+
15+
export default async function Profile() {
16+
const user = await getUserData();
17+
return user ? <pre>{JSON.stringify(user, null, 2)}</pre> : null;
18+
}

with-nextjs-13/components/nav.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { useAuthorizer } from '@authorizerdev/authorizer-react';
2+
import Link from 'next/link';
3+
import { useRouter } from 'next/navigation';
4+
5+
export default function Nav() {
6+
const { user, setUser, setToken, authorizerRef } = useAuthorizer();
7+
const router = useRouter();
8+
const onLogout = async () => {
9+
setUser(null);
10+
setToken(null);
11+
await authorizerRef.logout();
12+
await fetch('/api/logout');
13+
router.push('/');
14+
};
15+
return (
16+
<nav className="flex justify-between items-center w-full px-10 py-8 border-b">
17+
<div>
18+
<Link href="/">
19+
<h1>Authorizer Demo</h1>
20+
</Link>
21+
</div>
22+
<div>
23+
{user ? (
24+
<>
25+
<Link
26+
href="/profile"
27+
className="text-blue-500 hover:text-blue-400 mr-10"
28+
>
29+
Profile
30+
</Link>
31+
<button
32+
className="text-blue-500 hover:text-blue-400"
33+
onClick={onLogout}
34+
>
35+
Logout
36+
</button>
37+
</>
38+
) : (
39+
<>
40+
<Link href="/login" className="text-blue-500 hover:text-blue-400">
41+
Login
42+
</Link>
43+
</>
44+
)}
45+
</div>
46+
</nav>
47+
);
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default {
2+
authorizerURL: 'https://demo.authorizer.dev',
3+
redirectURL: 'http://localhost:3000',
4+
clientID: '96fed66c-9779-4694-a79a-260fc489ce33',
5+
};

with-nextjs-13/next.config.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* @type {import('next').NextConfig}
3+
*/
4+
const nextConfig = {
5+
experimental: { appDir: true },
6+
};
7+
8+
module.exports = nextConfig;

with-nextjs-13/package.json

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"private": true,
3+
"scripts": {
4+
"dev": "next dev",
5+
"build": "next build",
6+
"start": "next start",
7+
"turboDev": "concurrently \"next dev --turbo\" \"tailwindcss --input input.css --output output.css --watch\"",
8+
"turboBuild": "tailwindcss input.css --output output.css && next build"
9+
},
10+
"dependencies": {
11+
"@authorizerdev/authorizer-js": "^1.1.3",
12+
"@authorizerdev/authorizer-react": "^1.1.4",
13+
"next": "^13.0.5",
14+
"react": "18.2.0",
15+
"react-dom": "18.2.0",
16+
"styled-components": "^5.3.6"
17+
},
18+
"devDependencies": {
19+
"autoprefixer": "^10.4.0",
20+
"concurrently": "^7.5.0",
21+
"postcss": "^8.4.4",
22+
"tailwindcss": "^3.0.0"
23+
},
24+
"engines": {
25+
"node": ">= 14.0.0"
26+
}
27+
}

with-nextjs-13/pages/api/logout.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default function logoutAPI(req, res) {
2+
res.setHeader(
3+
'Set-Cookie',
4+
`authorizer-client=;Expires=-1;Secure=true;HttpOnly=true;Path=/`
5+
);
6+
res.status(200).json({ message: 'logged out successfully' });
7+
}

with-nextjs-13/pages/api/session.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
export default function sessionAPI(req, res) {
2+
const data = JSON.parse(req.body);
3+
const accessToken = data?.access_token;
4+
const expiresAt = data?.expires_in;
5+
if (!accessToken || !expiresAt) {
6+
res.status(401).json({
7+
message: 'Unauthorized',
8+
});
9+
} else {
10+
res.setHeader(
11+
'Set-Cookie',
12+
`authorizer-client-next=${accessToken};Secure=true;HttpOnly=true;Path=/`
13+
);
14+
res.status(200).json({ message: 'session created successfully' });
15+
}
16+
}

with-nextjs-13/postcss.config.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// If you want to use other PostCSS plugins, see the following:
2+
// https://tailwindcss.com/docs/using-with-preprocessors
3+
module.exports = {
4+
plugins: {
5+
tailwindcss: {},
6+
autoprefixer: {},
7+
},
8+
}

with-nextjs-13/public/favicon.ico

14.7 KB
Binary file not shown.

with-nextjs-13/public/vercel.svg

+4
Loading

with-nextjs-13/styles/globals.css

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;

with-nextjs-13/tailwind.config.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/** @type {import('tailwindcss').Config} */
2+
module.exports = {
3+
content: [
4+
'./app/**/*.{js,ts,jsx,tsx,css}',
5+
'./components/**/*.{js,ts,jsx,tsx}',
6+
],
7+
theme: {
8+
extend: {},
9+
},
10+
plugins: [],
11+
};

0 commit comments

Comments
 (0)