Files
hanko/docs/docs/guides/next.mdx
2023-03-03 11:06:23 +01:00

177 lines
5.7 KiB
Plaintext

---
title: Next.js + Hanko
sidebar_label: Next.js
keywords: [next, nextjs]
sidebar_custom_props:
docCardIconName: nextjs-dark
---
# Next.js
In this guide you will learn how to use the
[hanko-elements](https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md) web components to
add authentication and a user profile to your Next.js application.
## Install dependencies
Install the `@teamhanko/hanko-elements` package:
```shell npm2yarn
npm install @teamhanko/hanko-elements
```
## Add `<hanko-auth>` component
To provide a login interface in your app, use the `<hanko-auth>` web component. To do so, first import the `register`
function from `@teamhanko/hanko-elements` in your Next.js component. Then call `register` to register the `<hanko-auth>`
element with the browser's [`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry)
and use the `<hanko-auth>` element in your JSX.
:::info
When adding the `<hanko-auth>` element to your JSX you must provide the URL of the Hanko API via the `api`
attribute. If you are using [Hanko Cloud](https://cloud.hanko.io), you can find the API URL on your project dashboard.
If you are self-hosting you need to provide the URL of your running Hanko backend.
:::
```jsx title="HankoAuth.jsx" showLineNumbers
import { register } from "@teamhanko/hanko-elements";
const hankoApi = "<YOUR_API_URL>";
export default function HankoAuth() {
useEffect(() => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
register({ shadow: true })
.catch((error) => {
// handle error
});
}, []);
return (
<hanko-auth api={hankoApi} />
);
}
```
The call to `register` attempts to register the `<hanko-auth>` element with the
browser's [`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry) through a
call to `window.customElements.define()`.
Next.js pre-renders pages on the server but the browser `window` is not available during pre-rendering, so the custom
element registration would fail.
A solution for this is to use Next's [dynamic import](https://nextjs.org/docs/advanced-features/dynamic-import) feature
to dynamically load the component on the client-side and disable server rendering for it:
```jsx title="index.js" showLineNumbers
import dynamic from "next/dynamic";
export default function Home() {
const HankoAuth = dynamic(
// replace with path to your component using the <hanko-auth> element
() => import('../components/HankoAuth'),
{ ssr: false },
)
return (
<Suspense fallback={"Loading ..."}>
<HankoAuth/>
</Suspense>
)
}
```
### Define login callbacks
The `<hanko-auth>` element dispatches a custom `hankoAuthSuccess` event on successful login. React to this
event in order to, for example, redirect your users to protected pages in your application,
e.g. a [user profile page](#hanko-profile).
To do so, apply an event listener with an appropriate redirect callback:
```jsx {2,10-19} title="HankoAuth.jsx" showLineNumbers
import React, { useEffect, useCallback } from "react";
import { useRouter } from "next/router";
import { register } from "@teamhanko/hanko-elements";
const hankoApi = "<YOUR_API_URL>";
export default function HankoAuth() {
const router = useRouter();
const redirectAfterLogin = useCallback(() => {
// successfully logged in, redirect to a page in your application
router.replace("...");
}, [router]);
useEffect(() => {
document.addEventListener("hankoAuthSuccess", redirectAfterLogin);
return () =>
document.removeEventListener("hankoAuthSuccess", redirectAfterLogin);
}, [redirectAfterLogin]);
useEffect(() => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
register({ shadow: true })
.catch((error) => {
// handle error
});
}, []);
return (
<hanko-auth api={hankoApi} />
);
}
```
## Add `<hanko-profile>` component {#hanko-profile}
To provide a page where users can manage their email addresses, password and passkeys, use the `<hanko-profile>` web
component. Just as with the `<hanko-auth>` component, import the `register` function from `@teamhanko/hanko-elements` in
your Next.js component. Then call `register` to register the `<hanko-profile>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry) and use
the element in your JSX.
:::info
When adding the `<hanko-profile>` element to your template you must provide the URL of the Hanko API via the `api`
attribute. If you are using [Hanko Cloud](https://cloud.hanko.io), you can find the API URL on your project dashboard.
If you are self-hosting you need to provide the URL of your running Hanko backend.
:::
```jsx title="HankoProfile.jsx" showLineNumbers
import { useEffect } from "react";
import { register } from "@teamhanko/hanko-elements";
const hankoApi = "<YOUR_API_URL>";
export default function HankoProfile() {
useEffect(() => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
register({ shadow: true })
.catch((error) => {
// handle error
});
}, []);
return (
<hanko-profile api={hankoApi} />
);
};
```
## Customize component styles
The styles of the `hanko-auth` and `hanko-profile` elements can be customized using CSS variables and parts. See our
guide on customization [here](https://github.com/teamhanko/hanko/tree/main/frontend/elements#ui-customization).
## Authenticate backend requests
If you want to authenticate requests in your own backend, please view our [backend guide](/guides/backend).