<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PP7S83N" height="0" width="0" style="display:none;visibility:hidden">
Tutorial

What to do first with Refine

This tutorial will guide you in providing a context that will integrate your Refine powered app with the Weavy API for authentication.

Have your favorite code editor ready, and let's get started!

1. Weavy API Key

First we need an API key to communicate with the Weavy backend.

2. Prepare your Refine app

Make sure you have a Refine powered app. For this tutorial we make use of NextJS with NextAuth.

Refine has a ready-to-go Authentication with NextAuth.js example for this.

npm create refine-app@latest -- --example with-nextjs-next-auth

3. Configure environment variables

To securely handle the Weavy configuration, we provide the environment url and the API key as environment variables.

NextJS has built in support to handle environment variables. All the environment variables are available server side while variables that should be accessed on the client side needs to be prefixed with NEXT_PUBLIC_.

Place the environment variables in a .env file in the root of your project.

.env
NEXT_PUBLIC_WEAVY_URL="WY_BACKEND_URL"
WEAVY_APIKEY="WY_API_*****************"

4. Install @weavy/uikit-react

Now that you have your Refine project ready and running using your favorite code editor, we can install the @weavy/uikit-react package from npm.

The uikit-react package is using the uikit-web components under the hood and any new releases will come in both packages.

Simply install the package in your project to get going!

npm install @weavy/uikit-react

5. Add authentication

We use a provider to handle the communication between Refine authentication and Weavy API. The provider gets the authenticated user in your app, syncs it with Weavy, and returns an access token.

The provider makes use of React Server Actions to keep the handling secure on the server side.

  • Create a provider for Weavy server actions in /src/app/provider/weavy/authentication.ts.
  • Make sure that it runs server side by adding the "use server"; directive in the top of the file.
  • First we provide an async getAuthenticatedUser() function for getting the user data from the NextAuth authentication framework. You can customize this function to fit your authentication framework.
  • Add an async updateUser() function for updating the user in the Weavy environment using the API key.
  • Add an async tokenFactory() function that is fetching a token for the current user.
/src/app/provider/weavy/authentication.ts
"use server"
import authOptions from "@app/api/auth/[...nextauth]/options"
import { getServerSession } from "next-auth"

export type WeavyUser = {
  name?: string | null
  email?: string | null
  picture?: string | null
}

export const getAuthenticatedUser = async () => {
  const session = await getServerSession(authOptions)

  if (!session || !session.user) {
    throw new Error("No authenticated user")
  }
  const uid = `refine-user-${session.user.email}`
  const weavyUser: WeavyUser = {
    name: session.user.name,
    email: session.user.email,
    picture: session.user.image,
  }
  return { uid, weavyUser }
}

export const tokenFactory = async (refresh: boolean = false) => {
  const user = await getAuthenticatedUser()

  // fetch access_token from server
  const response = await fetch(new URL(`/api/users/${user.uid}/tokens`, process.env.NEXT_PUBLIC_WY_URL), {
    method: "POST",
    headers: {
      "content-type": "application/json",
      Authorization: `Bearer ${process.env.WY_APIKEY}`,
    },
    body: JSON.stringify({ expires_in: 3600 }),
  })

  if (response.ok) {
    const data = await response.json()

    // return access_token to UIKit
    return data.access_token as string
  } else {
    throw new Error("Could not fetch token")
  }
}

export const updateUser = async () => {
  const user = await getAuthenticatedUser()

  console.log("Updating weavy user", user.uid)

  const response = await fetch(new URL(`/api/users/${user.uid}`, process.env.NEXT_PUBLIC_WY_URL), {
    method: "PUT",
    headers: {
      "content-type": "application/json",
      Authorization: `Bearer ${process.env.WY_APIKEY}`,
    },
    body: JSON.stringify(user.weavyUser),
  })

  if (!response.ok) {
    throw new Error("Could not update user")
  }
}

6. Add a Weavy Context

Now that we have our server actions ready, we make use of it in a client side component that triggers the user sync and links the authentication to Weavy.

  • Create a context component in /src/app/contexts/weavy/context.tsx.
  • Make sure to add the "use client" directive in the top to make it a client side component.
  • Add a useEffect() hook to call the updateUser() server action when the user is authenticated.
  • Import the WyContext component from @weavy/uikit-react and add it to the return render of your context component.
  • Provide <WyContext> with the url to your Weavy environment. Provide it as a string or make use of the NEXT_PUBLIC_WY_URL env variable.
  • Provide the tokenFactory() server action to <WyContext> using the tokenFactory property.
/src/app/contexts/weavy/context.tsx
"use client"
import { useIsAuthenticated } from "@refinedev/core"
import { WyContext } from "@weavy/uikit-react"
import React, { useEffect } from "react"
import { tokenFactory, updateUser } from "@providers/weavy/authentication"

export const WeavyContextProvider = (props: React.PropsWithChildren) => {
  const { data: identity } = useIsAuthenticated()

  useEffect(() => {
    if (identity?.authenticated) {
      updateUser()
    }
  }, [identity?.authenticated])

  return (
    <WyContext url={process.env.NEXT_PUBLIC_WY_URL} tokenFactory={tokenFactory}>
        {props.children}
    </WyContext>
  )
}

7. Use the Weavy context

To make use of the Weavy context provider component, we need to place it inside the <Refine> component.

The <Refine> component should be place within the layout of your app and is usually found in /src/app/layout.tsx.

In this case the <Refine> component is provided inside the <RefineContext> component, so we can just place the Weavy context provider there.

Simply import your <WeavyContextProvider> context  component from @contexts/weavy/context and place it inside <RefineContext> wrapping the {props.children}.

Place <WeavyContextProvider> within your <Refine> context
import { WeavyContextProvider } from "@contexts/weavy/context"

...

<RefineContext defaultMode={theme?.value}>
  <WeavyContextProvider>{children}</WeavyContextProvider>
</RefineContext>

8. Done!

We now have the foundation to start adding Weavy features to your app.

Let's start building!

refine-screen
Ask AI
Support

To access live chat with our developer success team you need a Weavy account.

Sign in or create a Weavy account