Skip to content

React

Initialization

In your React application, create a src/auth.ts file that allows to make authenticated requests to the backend like this:

ts
import { createClient, LoginRequiredError } from '@featherscloud/auth'

export const appId = '<your-app-id>'

export const auth = createClient({ appId })

/**
 * Make an authenticated request using the fetch API or
 * redirect to the login page if the user needs to log in.
 * 
 * @param url The URL for the request
 * @param options Additional request options.
 * @returns The fetch response
 */
export async function authFetch(url: string, options?: RequestInit) {
  const headers = new Headers(options?.headers)

  try {
    // Set the authorization header with the Feathers Cloud Auth token
    headers.set('Authorization', await auth.getHeader())
  } catch (error) {
    if (error instanceof LoginRequiredError) {
      // Redirect to login page if a login is required
      window.location.href = await auth.getLoginUrl(error)
    } else {
      // Throw any other error
      throw error
    }
  }

  return fetch(url, {
    ...options,
    headers
  })
}

This file exports an authFetch function that can be used just like the normal fetch API and will redirect to the login page if the user needs to log in.

Usage

A React component using this function and loading the message from one of the platform example servers can look like this:

tsx
import { useEffect, useState } from 'react'

import './App.css'
import { authFetch } from './auth'

async function loadMessage() {
  // Get data with authentication from your server
  const response = await authFetch('http://localhost:3030/message', {
    method: 'GET'
  });

  if (response.status >= 400) {
    throw new Error(`Failed to load message: ${response.statusText}`);
  }

  return response.json();
}

function App() {
  const [message, setMessage] = useState('')

  useEffect(() => {
    loadMessage().then(({ message }) => setMessage(message))
  }, [message])

  return (
    <>
      <h1>Feathers Cloud Auth React Demo</h1>
      <div className="card">
        <p>The message from the server is:</p>
      </div>
      <h2>{message}</h2>
    </>
  )
}

export default App

You can find the full Vite + React example application here.