Closed2

urlqメモ

ふっけふっけ

NextJS

next-urqlを導入することでNextJSに対応できる。
今回はNextJS(pages)に導入する。

できること

  • getServerSidePropsなどSSRで取得したデータがクライアントのuseQueryの初期値になる。

https://formidable.com/open-source/urql/docs/advanced/server-side-rendering/#legacy-nextjs-pages

  1. クライアント側でデータ取得できるようにラップする。
const function Index() {
  const [] = useQuery();   // ここでつかえる
  return (<></>);
}
export default withUrqlClient((ssrExchange) => ({
  url: '',
  exchanges: [cacheExchange, ssrExchange, fetchExchange],
}))(Index);
  1. getServerSidePropsでデータ取得する
export async function getServerSideProps() {
  const ssrCache = ssrExchange({ isClient: false });
  const client = initUrqlClient(
    {
      url: '',
      },
      exchanges: [cacheExchange, ssrCache, fetchExchange],
    },
    false,
  );
  await client
    .query()
    .toPromise();

  return {
    props: {
      urqlState: ssrCache.extractData(), // urqlStateにすることでuseQueryの初期値になる
    },
  };
}
ふっけふっけ

AWS Cognitoとの連携
urqlのauthExchangeをつかう

import { authExchange } from '@urql/exchange-auth';
import { Auth } from 'aws-amplify';

export const cognitoExchange = authExchange(async (/* utils */) => {
  const session = await Auth.currentSession().catch(() => undefined);
  let token = session?.getIdToken().getJwtToken();
  return {
    addAuthToOperation(operation) {
      const { fetchOptions } = operation.context;
      const options =
        typeof fetchOptions === 'function' ? fetchOptions() : fetchOptions;

      const headers = {
        ...options?.headers,
        'x-api-key': env.NEXT_PUBLIC_API_KEY,
      };

      const context = {
        ...operation.context,
        url: env.NEXT_PUBLIC_PUBLIC_API_DOMAIN,
        fetchOptions: {
          ...options,
          headers,
        },
      };
      return makeOperation(operation.kind, operation, context);
    },
    didAuthError(error) {
      return error.graphQLErrors.some(
        ({ message }) =>
          message === 'Unauthorized' ||
          message === 'Access denied' ||
          message === 'Not authenticated' ||
          message === 'Token has expired.',
      );
    },
    async refreshAuth() {
      const refreshedSession = await Auth.currentSession().catch(
        () => undefined,
      );
      token = refreshedSession?.getIdToken().getJwtToken();
    },
  };
});

このスクラップは2024/07/25にクローズされました