javascriptnext.jsnext-authtwitch-apiswr

How to properly pass headers when using SWR?


I have decided to attempt to move majority of my API function to SWR as it simply allows me to do so much more!

Problem

However, I am having a huge issue where I cannot figure out how to properly pass headers into SWR. I've looked at the docs and more and yet nothing seems to do the trick. I am using Twitch API, Next.js and NextAuth for handling tokens, sessions, etc. I have left my GitHub repo below along with the code I am currently trying to use.

Note:

I console log the error return if an error occurs yet, when I access the page /dash it says failed to load yet there is no console log of an error?

Github Repo

import axios from "axios";
import Link from "next/link";
import {
  VStack,
  Heading,
  Divider,
  Text,
  Box,
  Badge,
  Center,
} from "@chakra-ui/react";
import { useSession } from "next-auth/react"
import useSWR from 'swr'

const fetcher = (url) => {
  const { data: session, status } = useSession()
  axios
    .get(url, { 
        headers: { 
          'Authorization': `Bearer ${session.accessToken}`,
          'Client-Id': `${process.env.TWITCH_CLIENT_ID}`
        }})
    .then((res) => res.data);
}
     
function Dash () {
  const { data, error } = useSWR(`https://api.twitch.tv/helix/streams/key?broadcaster_id=630124067`,fetcher)
  
  if (error) return (
    console.log(error),
    <div>Failed to load</div>
  )
  if (!data) return <div>loading...</div>

  return (
    <VStack>
      <Text>{data.user_name}</Text>
    </VStack>
  )
}

export default Dash

Solution

  • TL;DR: You can use an array as the key parameter in useSWR to pass multiple arguments to the fetcher function.


    First, useSession is a React hook, and should only be called at the top level of a React component/another hook. This avoids breaking the Rules of Hooks.

    Second, you should move the useSession call to the Dash component. You can then call the fetcher conditionally (see Conditional Fetching) when the session exists, and pass the accessToken to the fetcher method using an array as the key parameter.

    function Dash() {
        const { data: session } = useSession()
    
        const { data, error } = useSWR(
            session ? ['https://api.twitch.tv/helix/streams/key?broadcaster_id=630124067', session.accessToken] : null, 
            fetcher
        )
      
        // Remaining code
    }
    

    Lastly, your fetcher function will have to be modified slightly to accept the accessToken parameter. Note that you also need a return statement on the axios call for it to return the data properly.

    const fetcher = (url, accessToken) => {
        return axios
            .get(url, { 
                headers: { 
                    'Authorization': `Bearer ${accessToken}`,
                    'Client-Id': `${process.env.TWITCH_CLIENT_ID}`
                }
            })
            .then((res) => res.data);
    }