diff --git a/articles/quickstart/webapp/nextjs/01-login.md b/articles/quickstart/webapp/nextjs/01-login.md index fca09747b7..80cb7b4656 100644 --- a/articles/quickstart/webapp/nextjs/01-login.md +++ b/articles/quickstart/webapp/nextjs/01-login.md @@ -26,7 +26,7 @@ Run the following command within your project directory to install the Auth0 Nex npm install @auth0/nextjs-auth0 ``` -The SDK exposes methods and variables that help you integrate Auth0 with your Next.js application using [API Routes](https://nextjs.org/docs/api-routes/introduction) on the backend and [React Context](https://reactjs.org/docs/context.html) with [React Hooks](https://reactjs.org/docs/hooks-overview.html) on the frontend. +The SDK exposes methods and variables that help you integrate Auth0 with your Next.js application using [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) on the backend and [React Context](https://reactjs.org/docs/context.html) with [React Hooks](https://reactjs.org/docs/hooks-overview.html) on the frontend. ### Configure the SDK @@ -48,17 +48,17 @@ AUTH0_CLIENT_SECRET='${account.clientSecret}' The SDK will read these values from the Node.js process environment and automatically configure itself. -### Add the dynamic API route +### Add the dynamic API route handler -Create an `auth` directory under the `pages/api` directory. Under this newly created `auth` directory, create a `[auth0].js` file. The path to your [dynamic API route](https://nextjs.org/docs/api-routes/dynamic-api-routes) file should then be `pages/api/auth/[auth0].js`. +Create a file at `app/api/auth/[auth0]/route.js`. This is your Route Handler file with a [Dynamic Route Segment](https://nextjs.org/docs/app/building-your-application/routing/route-handlers#dynamic-route-segments). -Then, import in that file the `handleAuth` method from the SDK, and export the result of calling it. +Then, import the `handleAuth` method from the SDK, and export the result of calling it from the `GET` export. ```javascript -// pages/api/auth/[auth0].js +// app/api/auth/[auth0]/route.js import { handleAuth } from '@auth0/nextjs-auth0'; -export default handleAuth(); +export const GET = handleAuth(); ``` This creates the following routes: @@ -70,29 +70,26 @@ This creates the following routes: ### Add the `UserProvider` component -On the frontend side, the SDK uses React Context to manage the authentication state of your users. To make that state available to all your pages, you need to override the [App component](https://nextjs.org/docs/advanced-features/custom-app) and wrap its inner component with a `UserProvider`. +On the frontend side, the SDK uses React Context to manage the authentication state of your users. To make that state available to all your pages, you need to override the [Root Layout component](https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts#root-layout-required) and wrap the `` tag with a `UserProvider` in the file `app/layout.jsx`. -:::note -Support for the new `app` directory is coming. Check out the [beta release](https://github.com/auth0/nextjs-auth0/issues/1235). -::: - -Create the file `pages/_app.js` as follows: +Create the file `app/layout.jsx` as follows: ```jsx -// pages/_app.js -import React from 'react'; +// app/layout.jsx import { UserProvider } from '@auth0/nextjs-auth0/client'; -export default function App({ Component, pageProps }) { +export default function RootLayout({ children }) { return ( + - + {children} + ); } ``` -The authentication state exposed by `UserProvider` can be accessed in any component using the `useUser()` hook. +The authentication state exposed by `UserProvider` can be accessed in any Client Component using the `useUser()` hook. :::panel Checkpoint Now that you have added the dynamic route and `UserProvider`, run your application to verify that your application is not throwing any errors related to Auth0. @@ -134,13 +131,18 @@ Add the logout link to your application. When you click it, verify that your Nex ## Show User Profile Information -The Auth0 Next.js SDK helps you retrieve the [profile information](https://auth0.com/docs/users/user-profiles) associated with the logged-in user, such as their name or profile picture, to personalize the user interface. The profile information is available through the `user` property exposed by the `useUser()` hook. Take this `Profile` component as an example of how to use it: +The Auth0 Next.js SDK helps you retrieve the [profile information](https://auth0.com/docs/users/user-profiles) associated with the logged-in user, such as their name or profile picture, to personalize the user interface. + +### From a Client Component + +The profile information is available through the `user` property exposed by the `useUser()` hook. Take this [Client Component](https://nextjs.org/docs/getting-started/react-essentials#client-components) as an example of how to use it: ```jsx -import React from 'react'; +'use client'; + import { useUser } from '@auth0/nextjs-auth0/client'; -export default function Profile() { +export default function ProfileClient() { const { user, error, isLoading } = useUser(); if (isLoading) return
Loading...
; @@ -164,6 +166,28 @@ The `user` property contains sensitive information and artifacts related to the - Ensure that the SDK has loaded successfully by checking that no `error` was produced. - Check the `user` property to ensure that Auth0 has authenticated the user before React renders any component that consumes it. +### From a Server Component + +The profile information is available through the `user` property exposed by the `getSession` function. Take this [Server Component](https://nextjs.org/docs/getting-started/react-essentials#server-components) as an example of how to use it: + +```jsx +import { getSession } from '@auth0/nextjs-auth0'; + +export default async function ProfileServer() { + const { user } = await getSession(); + + return ( + user && ( +
+ {user.name} +

{user.name}

+

{user.email}

+
+ ) + ); +} +``` + :::panel Checkpoint Verify that you can display the `user.name` or [any other](https://auth0.com/docs/users/user-profile-structure#user-profile-attributes) `user` property within a component correctly after you have logged in. ::: diff --git a/articles/quickstart/webapp/nextjs/files/app.md b/articles/quickstart/webapp/nextjs/files/app.md deleted file mode 100644 index e65d5bf83c..0000000000 --- a/articles/quickstart/webapp/nextjs/files/app.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: _app.jsx -language: jsx ---- - - - -```jsx -import React from 'react'; -import { UserProvider } from '@auth0/nextjs-auth0/client'; - -export default function App({ Component, pageProps }) { - return ( - - - - ); -} -``` diff --git a/articles/quickstart/webapp/nextjs/files/auth.md b/articles/quickstart/webapp/nextjs/files/auth.md index e67997294f..f1cf51ee54 100644 --- a/articles/quickstart/webapp/nextjs/files/auth.md +++ b/articles/quickstart/webapp/nextjs/files/auth.md @@ -1,5 +1,5 @@ --- -name: "[...auth0].js" +name: "app/api/[auth0]/route.js" language: javascript --- @@ -8,5 +8,5 @@ language: javascript ```javascript import { handleAuth } from '@auth0/nextjs-auth0'; -export default handleAuth(); +export const GET = handleAuth(); ``` diff --git a/articles/quickstart/webapp/nextjs/files/layout.md b/articles/quickstart/webapp/nextjs/files/layout.md new file mode 100644 index 0000000000..8567031642 --- /dev/null +++ b/articles/quickstart/webapp/nextjs/files/layout.md @@ -0,0 +1,20 @@ +--- +name: "app/layout.jsx" +language: jsx +--- + + + +```jsx +import { UserProvider } from '@auth0/nextjs-auth0/client'; + +export default function RootLayout({ children }) { + return ( + + + {children} + + + ); +} +``` diff --git a/articles/quickstart/webapp/nextjs/files/login.md b/articles/quickstart/webapp/nextjs/files/login.md index 53df8911e1..e245a0cbbd 100644 --- a/articles/quickstart/webapp/nextjs/files/login.md +++ b/articles/quickstart/webapp/nextjs/files/login.md @@ -1,5 +1,5 @@ --- -name: login.jsx +name: "app/login.jsx" language: jsx --- diff --git a/articles/quickstart/webapp/nextjs/files/logout.md b/articles/quickstart/webapp/nextjs/files/logout.md index 406a8bbe1a..60fa22031e 100644 --- a/articles/quickstart/webapp/nextjs/files/logout.md +++ b/articles/quickstart/webapp/nextjs/files/logout.md @@ -1,5 +1,5 @@ --- -name: logout.jsx +name: "app/logout.jsx" language: jsx --- diff --git a/articles/quickstart/webapp/nextjs/files/profile.md b/articles/quickstart/webapp/nextjs/files/profile-client.md similarity index 83% rename from articles/quickstart/webapp/nextjs/files/profile.md rename to articles/quickstart/webapp/nextjs/files/profile-client.md index ff550f92d9..a4ae7102fe 100644 --- a/articles/quickstart/webapp/nextjs/files/profile.md +++ b/articles/quickstart/webapp/nextjs/files/profile-client.md @@ -1,15 +1,16 @@ --- -name: profile.jsx +name: "app/profile-client/page.jsx" language: jsx --- ```jsx -import React from 'react'; +'use client'; + import { useUser } from '@auth0/nextjs-auth0/client'; -export default function Profile() { +export default function ProfileClient() { const { user, error, isLoading } = useUser(); if (isLoading) return
Loading...
; diff --git a/articles/quickstart/webapp/nextjs/files/profile-server.md b/articles/quickstart/webapp/nextjs/files/profile-server.md new file mode 100644 index 0000000000..1f164c403a --- /dev/null +++ b/articles/quickstart/webapp/nextjs/files/profile-server.md @@ -0,0 +1,24 @@ +--- +name: "app/profile-server/page.jsx" +language: jsx +--- + + + +```jsx +import { getSession } from '@auth0/nextjs-auth0'; + +export default async function ProfileServer() { + const { user } = await getSession(); + + return ( + user && ( +
+ {user.name} +

{user.name}

+

{user.email}

+
+ ) + ); +} +``` diff --git a/articles/quickstart/webapp/nextjs/index.yml b/articles/quickstart/webapp/nextjs/index.yml index 1fb0653abb..ad6a5b3b9a 100644 --- a/articles/quickstart/webapp/nextjs/index.yml +++ b/articles/quickstart/webapp/nextjs/index.yml @@ -23,7 +23,7 @@ seo_alias: nextjs show_releases: true show_steps: true requirements: - - Next.js 10+ + - Next.js 13.4+ default_article: 01-login articles: - 01-login diff --git a/articles/quickstart/webapp/nextjs/interactive.md b/articles/quickstart/webapp/nextjs/interactive.md index 102fcfcb27..fff30cd7b1 100644 --- a/articles/quickstart/webapp/nextjs/interactive.md +++ b/articles/quickstart/webapp/nextjs/interactive.md @@ -12,12 +12,13 @@ contentType: tutorial useCase: quickstart interactive: true files: - - files/env - - files/auth - - files/app - - files/login - - files/logout - - files/profile + - files/auth + - files/env + - files/layout + - files/login + - files/logout + - files/profile-client + - files/profile-server --- @@ -39,7 +40,7 @@ Run the following command within your project directory to install the Auth0 Nex npm install @auth0/nextjs-auth0 ``` -The SDK exposes methods and variables that help you integrate Auth0 with your Next.js application using [API Routes](https://nextjs.org/docs/api-routes/introduction) on the backend and [React Context](https://reactjs.org/docs/context.html) with [React Hooks](https://reactjs.org/docs/hooks-overview.html) on the frontend. +The SDK exposes methods and variables that help you integrate Auth0 with your Next.js application using [Route Handlers](https://nextjs.org/docs/app/building-your-application/routing/route-handlers) on the backend and [React Context](https://reactjs.org/docs/context.html) with [React Hooks](https://reactjs.org/docs/hooks-overview.html) on the frontend. ## Configure the SDK {{{ data-action=code data-code=".env.local" }}} @@ -53,44 +54,40 @@ In the root directory of your project, add the file `.env.local` with the follow The SDK will read these values from the Node.js process environment and automatically configure itself. -## Add the dynamic API route {{{ data-action=code data-code="[...auth0].js" }}} +## Add the dynamic Route Handler {{{ data-action=code data-code="app/api/[auth0]/route.js" }}} -Create an `auth` directory under the `pages/api` directory. Under this newly created `auth` directory, create a `[...auth0].js` file. The path to your [dynamic API route](https://nextjs.org/docs/api-routes/dynamic-api-routes) file should then be `pages/api/auth/[...auth0].js`. +Create a file at `app/api/auth/[auth0]/route.js`. This is your Route Handler file with a [Dynamic Route Segment](https://nextjs.org/docs/app/building-your-application/routing/route-handlers#dynamic-route-segments). -Then, import in that file the `handleAuth` method from the SDK, and export the result of calling it. This creates the following routes: +Then, import in that file the `handleAuth` method from the SDK, and export the result of calling it from the `GET` export. This creates the following routes: - `/api/auth/login`: The route used to perform login with Auth0. - `/api/auth/logout`: The route used to log the user out. - `/api/auth/callback`: The route Auth0 will redirect the user to after a successful login. - `/api/auth/me`: The route to fetch the user profile from. -## Add the `UserProvider` component {{{ data-action=code data-code="_app.jsx" }}} +## Add the `UserProvider` component {{{ data-action=code data-code="app/layout.jsx" }}} -On the frontend side, the SDK uses React Context to manage the authentication state of your users. To make that state available to all your pages, you need to override the [App component](https://nextjs.org/docs/advanced-features/custom-app) and wrap its inner component with a `UserProvider` in the file `pages/_app.jsx`. +On the frontend side, the SDK uses React Context to manage the authentication state of your users. To make that state available to all your pages, you need to override the [Root Layout component](https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts#root-layout-required) and wrap the `` tag with a `UserProvider` in the file `app/layout.jsx`. -:::note -Support for the new `app` directory is coming. Check out the [beta release](https://github.com/auth0/nextjs-auth0/issues/1235). -::: - -The authentication state exposed by `UserProvider` can be accessed in any component using the `useUser()` hook. +The authentication state exposed by `UserProvider` can be accessed in any Client Component using the `useUser()` hook. ::::checkpoint :::checkpoint-default -Now that you have added the dynamic route and `UserProvider`, run your application to verify that your application is not throwing any errors related to Auth0. +Now that you have added the route handler and `UserProvider`, run your application to verify that your application is not throwing any errors related to Auth0. ::: :::checkpoint-failure Sorry about that. Here's a couple of things to double check: * Are your environment variables populated correctly? -* did you put the `[...auth0].js` and `_app.jsx` files in the correct folder? +* did you put the `app/api/auth/[auth0]/route.js` and `app/layout.jsx` files in the correct folder? * make sure the domain and client ID are configured correctly Still having issues? Check out our [documentation](https://auth0.com/docs) or visit our [community page](https://community.auth0.com) to get more help. ::: :::: -## Add Login to Your Application {{{ data-action=code data-code="login.jsx" }}} +## Add Login to Your Application {{{ data-action=code data-code="app/login.jsx" }}} -Users can now log in to your application by visiting the `/api/auth/login` route provided by the SDK. Add a link that points to the login route using an **anchor tag**. Clicking it redirects your users to the Auth0 Universal Login Page, where Auth0 can authenticate them. Upon successful authentication, Auth0 will redirect your users back to your application. +Users can now log in to your application by visiting the `/api/auth/login` route handler provided by the SDK. Add a link that points to the login route using an **anchor tag**. Clicking it redirects your users to the Auth0 Universal Login Page, where Auth0 can authenticate them. Upon successful authentication, Auth0 will redirect your users back to your application. :::note Next linting rules might suggest using the `Link` component instead of an anchor tag. The `Link` component is meant to perform [client-side transitions between pages](https://nextjs.org/docs/api-reference/next/link). As the link points to an API route and not to a page, you should keep it as an anchor tag. @@ -115,7 +112,7 @@ Still having issues? Check out our [documentation](https://auth0.com/docs) or vi <%= include('../_includes/_auth_note_dev_keys') %> -## Add Logout to Your Application {{{ data-action=code data-code="logout.jsx" }}} +## Add Logout to Your Application {{{ data-action=code data-code="app/logout.jsx" }}} Now that you can log in to your Next.js application, you need [a way to log out](https://auth0.com/docs/logout/log-users-out-of-auth0). Add a link that points to the `/api/auth/logout` API route. Clicking it redirects your users to your [Auth0 logout endpoint](https://auth0.com/docs/api/authentication?javascript#logout) (`https://YOUR_DOMAIN/v2/logout`) and then immediately redirects them back to your application. @@ -132,15 +129,11 @@ Still having issues? Check out our [documentation](https://auth0.com/docs) or vi ::: :::: -## Show User Profile Information {{{ data-action=code data-code="profile.jsx" }}} +## Show User Profile Information from a Client Component{{{ data-action=code data-code="app/profile-client/page.jsx" }}} -The Auth0 Next.js SDK helps you retrieve the [profile information](https://auth0.com/docs/users/user-profiles) associated with the logged-in user, such as their name or profile picture, to personalize the user interface. The profile information is available through the `user` property exposed by the `useUser()` hook. Take this `Profile` page component as an example of how to use it. +The Auth0 Next.js SDK helps you retrieve the [profile information](https://auth0.com/docs/users/user-profiles) associated with the logged-in user, such as their name or profile picture, to personalize the user interface. -The `user` property contains sensitive information and artifacts related to the user's identity. As such, its availability depends on the user's authentication status. To prevent any render errors: - -- Ensure that the SDK has completed loading before accessing the `user` property by checking that `isLoading` is `false`. -- Ensure that the SDK has loaded successfully by checking that no `error` was produced. -- Check the `user` property to ensure that Auth0 has authenticated the user before React renders any component that consumes it. +The profile information is available through the `user` property exposed by the `useUser()` hook. Take this [Client Component](https://nextjs.org/docs/getting-started/react-essentials#client-components) `ProfileClient` as an example of how to use it. ::::checkpoint :::checkpoint-default @@ -155,3 +148,21 @@ Sorry about that. Here's a couple of things to double check: Still having issues? Check out our [documentation](https://auth0.com/docs) or visit our [community page](https://community.auth0.com) to get more help. ::: :::: + +## Show User Profile Information from a Server Component{{{ data-action=code data-code="app/profile-server/page.jsx" }}} + +The profile information is available through the `user` property exposed by the `getSession` function. Take this [Server Component](https://nextjs.org/docs/getting-started/react-essentials#server-components) `ProfileServer` as an example of how to use it. + +::::checkpoint +:::checkpoint-default +Verify that you can display the `user.name` or [any other](https://auth0.com/docs/users/user-profile-structure#user-profile-attributes) `user` property within a component correctly after you have logged in. +::: +:::checkpoint-failure +Sorry about that. Here's a couple of things to double check: +* are your environment variables populated correctly? +* make sure you have successfully logged in through the `/api/auth/login` handler. +* make sure there are no errors in the console + +Still having issues? Check out our [documentation](https://auth0.com/docs) or visit our [community page](https://community.auth0.com) to get more help. +::: +::::