Skip to content

Commit

Permalink
Add next.js auth helpers for server components (supabase#380)
Browse files Browse the repository at this point in the history
* add next.js auth helpers for server components

* update readmes

* update changeset

* fix build script for example

* fix: middleware setcookie.

* fix: middleware setcookie.

* remove pages ssr component

Co-authored-by: thorwebdev <[email protected]>
  • Loading branch information
dijonmusters and thorwebdev authored Nov 15, 2022
1 parent f1456ca commit 2be3f10
Show file tree
Hide file tree
Showing 34 changed files with 6,032 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changeset/purple-tomatoes-shout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@supabase/auth-helpers-nextjs': patch
---

feat: add helper for Next.js Server Components.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ A collection of framework specific Auth utilities for working with Supabase.

- Examples
- `@examples/nextjs`: a [Next.js](https://nextjs.org) app
- `@examples/nextjs-server-components`: a [Next.js](https://nextjs.org) 13 app with Server Components and `app` directory
- `@examples/sveltekit`: a [SvelteKit](https://kit.svelte.dev) app
- `@examples/sveltekit-email-password`: a [SvelteKit](https://kit.svelte.dev) app with SSR sign in
- `@examples/sveltekit-magic-link`: a [SvelteKit](https://kit.svelte.dev) app with magic links
Expand Down
4 changes: 4 additions & 0 deletions examples/nextjs-server-components/.env.local.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Update these with your Supabase details from your project settings > API
# https://app.supabase.com/project/_/settings/api
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
3 changes: 3 additions & 0 deletions examples/nextjs-server-components/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
36 changes: 36 additions & 0 deletions examples/nextjs-server-components/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
4 changes: 4 additions & 0 deletions examples/nextjs-server-components/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"typescript.tsdk": "./node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}
34 changes: 34 additions & 0 deletions examples/nextjs-server-components/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.

[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.

The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
26 changes: 26 additions & 0 deletions examples/nextjs-server-components/app/globals.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}

a {
color: inherit;
text-decoration: none;
}

* {
box-sizing: border-box;
}

@media (prefers-color-scheme: dark) {
html {
color-scheme: dark;
}
body {
color: white;
background: black;
}
}
10 changes: 10 additions & 0 deletions examples/nextjs-server-components/app/head.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default function Head() {
return (
<>
<title>Create Next App</title>
<meta content="width=device-width, initial-scale=1" name="viewport" />
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</>
)
}
38 changes: 38 additions & 0 deletions examples/nextjs-server-components/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import 'server-only';

import { headers, cookies } from 'next/headers';
import SupabaseListener from '../components/supabase-listener';
import Login from '../components/login';
import './globals.css';
import { createServerComponentSupabaseClient } from '@supabase/auth-helpers-nextjs';
import { Database } from '../db_types';

export default async function RootLayout({
children
}: {
children: React.ReactNode;
}) {
const supabase = createServerComponentSupabaseClient<Database>({
headers,
cookies
});

const {
data: { session }
} = await supabase.auth.getSession();

return (
<html lang="en">
{/*
<head /> will contain the components returned by the nearest parent
head.tsx. Find out more at https://beta.nextjs.org/docs/api-reference/file-conventions/head
*/}
<head />
<body>
<Login />
<SupabaseListener accessToken={session?.access_token} />
{children}
</body>
</html>
);
}
20 changes: 20 additions & 0 deletions examples/nextjs-server-components/app/optional-session/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'server-only';

import { headers, cookies } from 'next/headers';
import { createServerComponentSupabaseClient } from '@supabase/auth-helpers-nextjs';
import { Database } from '../../db_types';

// do not cache this page
export const revalidate = 0;

// this page will display with or without a user session
export default async function OptionalSession() {
const supabase = createServerComponentSupabaseClient<Database>({
headers,
cookies
});

const { data } = await supabase.from('posts').select('*');

return <pre>{JSON.stringify({ data }, null, 2)}</pre>;
}
146 changes: 146 additions & 0 deletions examples/nextjs-server-components/app/page.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
.container {
padding: 0 2rem;
}

.main {
min-height: 100vh;
padding: 4rem 0;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

.footer {
display: flex;
flex: 1;
padding: 2rem 0;
border-top: 1px solid #eaeaea;
justify-content: center;
align-items: center;
}

.footer a {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
}

.title {
margin: 0;
line-height: 1.15;
font-size: 4rem;
font-style: normal;
font-weight: 800;
letter-spacing: -0.025em;
}

.title a {
text-decoration: none;
color: #0070f3;
}

.title a:hover,
.title a:focus,
.title a:active {
text-decoration: underline;
}

.title,
.description {
text-align: center;
}

.description {
margin: 4rem 0;
line-height: 1.5;
font-size: 1.5rem;
}

.code {
background: #fafafa;
border-radius: 5px;
padding: 0.75rem;
font-size: 1.1rem;
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
Bitstream Vera Sans Mono, Courier New, monospace;
}

.grid {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
max-width: 1200px;
}

.card {
margin: 1rem;
padding: 1.5rem;
text-align: left;
color: inherit;
text-decoration: none;
border: 1px solid #eaeaea;
border-radius: 10px;
transition: color 0.15s ease, border-color 0.15s ease;
max-width: 300px;
}

.card:hover,
.card:focus,
.card:active {
color: #0070f3;
border-color: #0070f3;
}

.card h2 {
margin: 0 0 1rem 0;
font-size: 1.5rem;
}

.card p {
margin: 0;
font-size: 1.25rem;
line-height: 1.5;
}

.logo {
height: 1em;
margin-left: 0.5rem;
}

@media (max-width: 600px) {
.grid {
width: 100%;
flex-direction: column;
}
}

@media (prefers-color-scheme: dark) {
.title {
background: linear-gradient(180deg, #ffffff 0%, #aaaaaa 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-fill-color: transparent;
}
.title a {
background: linear-gradient(180deg, #0070f3 0%, #0153af 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-fill-color: transparent;
}
.card,
.footer {
border-color: #222;
}
.code {
background: #111;
}
.logo img {
filter: invert(1);
}
}
50 changes: 50 additions & 0 deletions examples/nextjs-server-components/app/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import Image from 'next/image';
import styles from './page.module.css';

export default function Home() {
return (
<div className={styles.container}>
<main className={styles.main}>
<h1 className={styles.title}>
Welcome to <a href="https://app.supabase.com">Supabase</a> on{' '}
<a href="https://nextjs.org">Next.js 13!</a>
</h1>

<p className={styles.description}>
Get started by editing{' '}
<code className={styles.code}>app/page.tsx</code>
</p>

<div className={styles.grid}>
<a href="/optional-session" className={styles.card}>
<h2>Optional Session &rarr;</h2>
<p>Visit this page with or without a session.</p>
</a>

<a href="/required-session" className={styles.card}>
<h2>Required Session &rarr;</h2>
<p>Get redirected if you don't have a session.</p>
</a>

<a href="/realtime" className={styles.card}>
<h2>Realtime &rarr;</h2>
<p>Merge server and client state with realtime.</p>
</a>
</div>
</main>

<footer className={styles.footer}>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
Powered by{' '}
<span className={styles.logo}>
<Image src="/vercel.svg" alt="Vercel Logo" width={72} height={16} />
</span>
</a>
</footer>
</div>
);
}
Loading

0 comments on commit 2be3f10

Please sign in to comment.