MSW(Mock Service Worker) in Next js first render not working - next.js

I use msw with Next js. But at First render, cannot connect api
this is index.tsx
import { useQuery } from "#tanstack/react-query";
import axios from "axios";
const Home = () => {
const getFruit = async () => {
const { data } = await axios.get("/api");
return data;
};
const { data } = useQuery(["dfa"], getFruit);
console.log("data: ", data);
return <div>Hello world</div>;
};
export default Home;
And i capture log in dev tool
In terminal compiling /_error (client and server).. error is showing.
I write code in mocks/index.ts like
async function initMocks() {
if (typeof window === "undefined") {
const { server } = await import("./server");
server.listen();
} else {
const { worker } = await import("./browser");
worker.start();
}
}
initMocks();
export {};
Also I check this code is running before index.tsx.
I think msw work late then first rendering. Is it right? How can I solve this problem?

Related

How to use async custom hook in Next.js middleware?

I have this custom hook:
const useRedirects = async () => {
const response = await fetch('/redirect/list')
const redirects = await response.json()
const checkRedirection = (url) => {
return {
isRedirected: // logic to check redirection
newUrl: // logic to form the new URL
}
}
return {
checkRedirection
}
}
export default useRedirects
And this is my middleware.js code:
import { NextResponse } from 'next/server'
import { useRedirect } from './UseRedirect'
export async function middleware(request) {
if (request.nextUrl.pathname.startsWith('/_next')) {
return
}
const checkRedirection = await useRedirect()
const { isRedirected, newUrl } = checkRedirection(request.nextUrl)
if (isRedirected) {
return newUrl
}
}
The problem is that, I get this error:
TypeError: Cannot read properties of null (reading 'length')
at eval (webpack-internal:///../../next/node_modules/next/dist/client/dev/error-overlay/hot-dev-client.js:262:55)
error - ../next/node_modules/#emotion/cache/dist/emotion-cache.browser.esm.js (461:0) #
error - document is not defined
So, how can I use an async hook inside my next.js middleware?

Apollo client can't query in Nextjs getServerSideProps via SchemaLink

Apollo client fails to do query when initialized with SchemaLink (nexus) instead of HttpLink. I get this error Cannot set properties of undefined (setting 'select')
function createIsomorphLink() {
if (typeof window === 'undefined') {
const { SchemaLink } = require('#apollo/client/link/schema')
const { schema } = require('./nexusSchema')
return new SchemaLink({ schema })
} else {
const { HttpLink } = require('#apollo/client/link/http')
return new HttpLink({
uri: '/api/graphql',
credentials: 'same-origin',
})
}
}
function createApolloClient() {
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: from([errorLink, createIsomorphLink()]),
cache: new InMemoryCache(),
})
}
Here's my getServerSideProps. I initialize apollo client and use apolloClient.query(...)
export const getServerSideProps = async ({ params }) => {
const id = params.id
const apolloClient = initializeApollo()
// Here's where the error occurs
const { data } = await apolloClient.query({
query: gql`
query findUniquePage($id: String!) {
findUniquePage(where: { id: $id }) {
title
type
content
isPublished
}
}
`,
variables: { id },
})
// ...snippet..
}
I tried creating simple 'hello' query with string response, so that there was no select part. But error stayed the same.
export const getServerSideProps = async () => {
const apolloClient = initializeApollo()
const { data } = await apolloClient.query({
query: gql`query hello { hello }`,
})
return {
props: {},
}
}
My apollo client version is 3.7.0. The latest is 3.7.1 but by CHANGELOG there seems to be nothing that addresses my issue. Probably, the problem is how apollo client requests my api via SchemaLink, or how my api parses that request (apollo server + code first nexus). Because when I replaced SchemaLink with HttpLink, code worked fine. But I kinda want to keep the SchemaLink. Any advice?

How can I use auth0 getSession() from nextjs middleware function, or is there some other way to get user particulars via middleware

I have this code in /pages/api/_middleware.js:
import { getSession } from '#auth0/nextjs-auth0'
export default async function middleware(req, ev) {
const session = await getSession(req)
console.log(session)
return NextResponse.next()
}
Whenever I run an API call that hits this I get this message:
error - node_modules#auth0\nextjs-auth0\dist\index.browser.js?b875 (11:0) # Object.getSession
Error: The getSession method can only be used from the server side
I'm not sure it's possible with the #auth0/nextjs-auth0 lib, but I'm lazily just checking if the appSession cookie is in storage like so:
import type { NextRequest } from 'next/server'
export function middleware(req: NextRequest) {
if (req.nextUrl.pathname === '/' && req.cookies.appSession) {
return Response.redirect('/app')
}
if (req.nextUrl.pathname === '/app' && !req.cookies.appSession) {
return Response.redirect('/')
}
}
you can get the session inside of the middleware like this.
import { NextRequest, NextResponse } from 'next/server';
import { withMiddlewareAuthRequired, getSession } from '#auth0/nextjs-auth0/edge';
export default withMiddlewareAuthRequired(async (req: NextRequest) => {
const res = NextResponse.next();
const user = await getSession(req, res);
if (user) {
// Do what you want...
}
return res;
});
// only work on the '/' path
export const config = {
matcher: '/',
};
Found it here, hope it helps!
https://github.com/auth0/nextjs-auth0/blob/main/EXAMPLES.md

How to initialize router before rendering anything in Nextjs?

I'm using react-query, when I get the id from the url and try to call it inside getSubject, it passes an undefined value http://localhost:3000/api/subject/undefined
but when I click a link from another component to get in this subject component it works but if refresh the page it does not work.
const router = useRouter()
const { id } = router.query
const { data } = useQuery('subjects', async () => await getSubject(id))
return value...
}
You should use getServerSideProps in this case. It has access to query params. On top of that you can prefetch data on the server side too.
export interface PageProps {
id: string;
}
export function Page({ id }: PageProps ) {
const { data } = useQuery('subjects', async () => await getSubject(id))
}
export const getServerSideProps: GetServerSideProps<PageProps > = async ({
params,
}) => {
const { id } = params;
return {
props: {
id,
},
};
};
If you still want to use router, you can wait for router.isReady flag. When it is true, query params should be parsed.

App working locally but not on production: TypeError: Cannot read property 'titulo_categoria' of undefined

I'm trying to deploy an app using Prismic as CMS and everything works perfectly locally, but once I deploy to vercel I get the error:
19:09:51.850 | TypeError: Cannot read property 'titulo_categoria' of undefined
There seems to be something wrong when it tries to get the data from Prismic.
My code is the following:
import {getAllCategorias, getCategory2} from '../../lib/api';
export default function Index({cat}) {
return <>{cat.titulo_categoria[0].text}</>;
}
export async function getStaticProps({params}) {
const data = await getCategory2(params.slug);
return {
props: {
cat: data?.categorias ?? null,
},
};
}
export async function getStaticPaths() {
const allPosts = await getAllCategorias();
return {
paths: allPosts?.map(({node}) => `/test/${node._meta.uid}`) || [],
fallback: true,
};
}
And the API code that gets data from Prismic is:
import Prismic from 'prismic-javascript';
const REPOSITORY = process.env.PRISMIC_REPOSITORY_NAME;
const REF_API_URL = `https://${REPOSITORY}.prismic.io/api/v2`;
const GRAPHQL_API_URL = `https://${REPOSITORY}.prismic.io/graphql`;
// export const API_URL = 'https://your-repo-name.cdn.prismic.io/api/v2'
export const API_TOKEN = process.env.PRISMIC_API_TOKEN;
export const API_LOCALE = process.env.PRISMIC_REPOSITORY_LOCALE;
export const PrismicClient = Prismic.client(REF_API_URL, {
accessToken: API_TOKEN,
});
async function fetchAPI(query, {previewData, variables} = {}) {
const prismicAPI = await PrismicClient.getApi();
const res = await fetch(
`${GRAPHQL_API_URL}?query=${query}&variables=${JSON.stringify(variables)}`,
{
headers: {
'Prismic-Ref': previewData?.ref || prismicAPI.masterRef.ref,
'Content-Type': 'application/json',
'Accept-Language': API_LOCALE,
Authorization: `Token ${API_TOKEN}`,
},
}
);
if (res.status !== 200) {
console.log(await res.text());
throw new Error('Failed to fetch API');
}
const json = await res.json();
if (json.errors) {
console.error(json.errors);
throw new Error('Failed to fetch API');
}
return json.data;
}
export async function getCategory2(slug) {
const data = await fetchAPI(
`
query CategoryBySlug($slug: String!, $lang: String!) {
categorias(uid: $slug, lang: $lang) {
titulo_categoria
_meta {
uid
}
}
}
`,
{
variables: {
slug,
lang: API_LOCALE,
},
}
);
return data;
}
Any idea what's wrong with this? I been trying to figure it out for the whole day without any luck
Perhaps you already checked that, but since you mentioned everything works locally and not on Vercel are you sure your environment variables are set there? Especially PRISMIC_API_TOKEN since it appears you're relying on it to query the API?
Also I'm a bit worried about that part of the code:
props: {
cat: data?.categorias ?? null,
}
...where you might be sending a null value to your Index component resulting in your error, I'd try that instead:
props: {
cat: data?.categorias ?? {},
}
...plus using the safe navigation operator (?.) on the Index component?
Let me know how it goes!

Resources