Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[EXPERIMENTAL] Next.js 13 app directory example #342

Closed
wants to merge 2 commits into from
Closed
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
2 changes: 2 additions & 0 deletions examples/nextjs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ yarn-error.log*

# typescript
*.tsbuildinfo

.vscode
12 changes: 12 additions & 0 deletions examples/nextjs/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html>
<head></head>
<body>{children}</body>
</html>
)
}
25 changes: 25 additions & 0 deletions examples/nextjs/app/nextjs-13/client-component/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Next.js 13 Client Component
// NOTE: This is experimental and used as research to understand how to support Next.js 13 in the future.
// https://beta.nextjs.org/docs/data-fetching/fetching#example-fetch-and-use-in-client-components

import { use } from 'react';
Copy link

@imbhargav5 imbhargav5 Oct 27, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 Will this be a client component without use client?

Edit: This is probably still in draft and you are probably working on it. Just thought this might have been missed.

import { createClient } from '@supabase/supabase-js';

async function getData() {
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL as string,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY as string
);

const {
data: { user }
} = await supabase.auth.getUser();
const { data } = await supabase.from('products').select('*').limit(1);

return { user, data };
}

export default function Page() {
const data = use(getData());
return <pre>{JSON.stringify(data, null, 2)}</pre>;
}
30 changes: 30 additions & 0 deletions examples/nextjs/app/nextjs-13/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Next.js 13
// NOTE: This is experimental and used as research to understand how to support Next.js 13 in the future.

import Link from 'next/link';

export default async function Page() {
return (
<>
<h1>Next.js 13 examples</h1>
<ul>
<li>
fetch and use in Client Components [
<Link href={'/nextjs-13/client-component'}>example</Link> |{' '}
<a href="https://beta.nextjs.org/docs/data-fetching/fetching#example-fetch-and-use-in-client-components">
docs
</a>
]
</li>
<li>
Dynamic Data (used to be getServerSideProps) [
<Link href={'/nextjs-13/ssr'}>example</Link> |{' '}
<a href="https://beta.nextjs.org/docs/data-fetching/fetching#dynamic-data">
docs
</a>
]
</li>
</ul>
</>
);
}
79 changes: 79 additions & 0 deletions examples/nextjs/app/nextjs-13/ssr/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Next.js 13 SSR
// NOTE: This is experimental and used as research to understand how to support Next.js 13 in the future.

import { cookies, headers } from 'next/headers';
import {
CookieOptions,
createBrowserSupabaseClient as _createBrowserSupabaseClient,
createServerSupabaseClient as _createServerSupabaseClient,
ensureArray,
filterCookies,
serializeCookie
} from '@supabase/auth-helpers-shared';

function createServerSupabaseClient<
Database = any,
SchemaName extends string & keyof Database = 'public' extends keyof Database
? 'public'
: string & keyof Database
>({
cookieOptions
}: {
cookieOptions?: CookieOptions;
} = {}) {
if (
!process.env.NEXT_PUBLIC_SUPABASE_URL ||
!process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
) {
throw new Error(
'NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY env variables are required!'
);
}

return _createServerSupabaseClient<Database, SchemaName>({
supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL,
supabaseKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
getRequestHeader: (key) => headers().get(key) ?? undefined,

getCookie(name) {
return cookies().get(name);
},
setCookie(name, value, options) {
// TODO: figure out how to access response object
// const newSetCookies = filterCookies(
// ensureArray(context.res.getHeader('set-cookie')?.toString() ?? []),
// name
// );
// const newSessionStr = serializeCookie(name, value, {
// ...options,
// // Allow supabase-js on the client to read the cookie as well
// httpOnly: false
// });
// context.res.setHeader('set-cookie', [...newSetCookies, newSessionStr]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, cookie().set() doesn't work in this case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are read-only functions: https://beta.nextjs.org/docs/upgrade-guide#accessing-request-object

But we're able to modify the res via middleware, see discussion here: #341 (comment)

},
options: {
global: {
// fetch // TODO: is this needed?
}
},
cookieOptions
});
}

// https://beta.nextjs.org/docs/data-fetching/fetching#segment-cache-configuration
export const cache = 'no-store';

async function getData() {
const supabase = createServerSupabaseClient();
const {
data: { user }
} = await supabase.auth.getUser();
const { data } = await supabase.from('users').select('*');

return { user, data };
}

export default async function Page() {
const data = await getData();
return <pre>{JSON.stringify(data, null, 2)}</pre>;
}
7 changes: 5 additions & 2 deletions examples/nextjs/next.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
experimental: {
appDir: true
}
};

module.exports = nextConfig
module.exports = nextConfig;
12 changes: 8 additions & 4 deletions examples/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,19 @@
"dependencies": {
"@supabase/auth-helpers-nextjs": "workspace:*",
"@supabase/auth-helpers-react": "workspace:*",
"@supabase/auth-helpers-shared": "workspace:*",
"@supabase/auth-ui-react": "^0.1.8",
"next": "^12.2.5",
"react": "17.0.2",
"react-dom": "17.0.2"
"@supabase/supabase-js": "^2.0.4",
"eslint-config-next": "^13.0.0",
"next": "^13.0.0",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@babel/core": ">=7.0.0 <8.0.0",
"@types/node": "^17.0.12",
"@types/react": "17.0.37",
"@types/react": "^18.0.23",
"@types/react-dom": "^18.0.7",
"config": "workspace:*",
"encoding": "^0.1.13",
"eslint": "7.32.0",
Expand Down
24 changes: 20 additions & 4 deletions examples/nextjs/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
Expand All @@ -13,8 +17,20 @@
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
"incremental": true,
"plugins": [
{
"name": "next"
}
]
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}
8 changes: 4 additions & 4 deletions packages/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
"license": "MIT",
"devDependencies": {
"@supabase/supabase-js": "2.0.4",
"@types/react": "^17.0.20",
"@types/react-dom": "^17.0.9",
"@types/react": "^18.0.23",
"@types/react-dom": "^18.0.7",
"config": "workspace:*",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"rimraf": "^3.0.2",
"tsconfig": "workspace:*",
"tsup": "^5.12.5",
Expand Down
Loading