I’m new to using next.JS, Graphql/Apollo so I’m trying to build a simple e-commerce page, I’m creating a page for a single product with the route /products/[id]
and I try to do Serverside Generation (SSG) by using getStaticPaths to generate all the paths and getStaticProps to return the product details but I keep getting an error that the paths are undefined in getStaticPaths. This is the error message I keep getting:
Error: Invalid `paths` value returned from getStaticPaths in /products/[id].
`paths` must be an array of strings or objects of shape { params: [key: string]: string }
This is my code for the page:
I’m currently using a graphql api
import {
useQuery,
} from '@apollo/client';
import { initializeApollo, PRODUCTS_API } from '../../../lib/apollo';
import { GET_ALL_PRODUCTS_QUERY, GET_SINGLE_PRODUCT_QUERY, allProductsQueryVars } from '../../../lib/queries';
import SingleProduct from '../../../components/SingleProduct';
export default function ProductPage({ id }) {
const {
loading, error, data,
} = useQuery(
GET_SINGLE_PRODUCT_QUERY,
{
variables: { id },
},
);
if (loading) return <p>Loading...</p>;
if (error) return <p>Error</p>;
if (data) {
const { product } = data;
return (
<SingleProduct product={product} />
);
}
}
export async function getStaticPaths() {
const client = initializeApollo();
const data = await client.query({
query: GET_ALL_PRODUCTS_QUERY,
variables: allProductsQueryVars,
});
const paths = data.products?.edges.map(({ node: { id } }) => ({
params: { id },
}));
return {
paths,
fallback: false,
};
}
export const getStaticProps = async ({ params }) => ({
props: {
id: params?.id,
},
});
This is my Apolloclient configuration code:
import merge from 'deepmerge';
import isEqual from 'lodash/isEqual';
import {
ApolloClient, InMemoryCache, HttpLink, from,
} from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { relayStylePagination } from '@apollo/client/utilities';
let apolloClient;
export const PRODUCTS_API = 'https://unicorn-staging.eu.saleor.cloud/graphql/';
const errorLink = onError(({ graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.forEach(({ message, locations, path }) => console.log(
`[GraphQL error]: Message: ${message}, Location: ${locations}, Path: ${path}`,
));
}
if (networkError) console.log(`[Network error]: ${networkError}`);
});
const httpLink = new HttpLink({
uri: PRODUCTS_API, // Server URL (must be absolute)
});
export const APOLLO_STATE_PROP_NAME = '__APOLLO_STATE__';
function createApolloClient() {
return new ApolloClient({
ssrMode: typeof window === 'undefined',
link: from([errorLink, httpLink]),
cache: new InMemoryCache({
typePolicies: {
Query: {
fields: {
products: relayStylePagination([]),
},
},
},
}),
});
}
export function initializeApollo(initialState) {
const _apolloClient = apolloClient ?? createApolloClient();
if (initialState) {
const existingCache = _apolloClient.cache.extract();
const data = merge(initialState, existingCache, {
arrayMerge: (destinationArray, sourceArray) => [
...sourceArray,
...destinationArray.filter((d) => sourceArray.every((s) => !isEqual(d, s))),
],
});
_apolloClient.cache.restore(data);
}
if (typeof window === 'undefined') {
return _apolloClient;
}
if (!apolloClient) {
apolloClient = _apolloClient;
}
return _apolloClient;
}
export function addApolloState(
client,
pageProps,
) {
if (pageProps?.props) {
pageProps.props[APOLLO_STATE_PROP_NAME] = client.cache.extract();
}
return pageProps;
}
and this is the graphql query and variable
export const GET_ALL_PRODUCTS_QUERY = gql`
query GetProducts($first: Int!, $after: String){
products(channel: "uk", first: $first, after: $after){
edges {
node {
id
name
rating
slug
description
isAvailable
thumbnail {
url
alt
}
category {
name
}
pricing {
priceRange {
start {
gross {
amount
}
}
stop {
gross {
amount
}
}
}
}
}
}
pageInfo {
hasNextPage
hasPreviousPage
startCursor
endCursor
}
totalCount
}
}
`;
export const allProductsQueryVars = {
first: 10,
after: '',
};
Please, any ideas on how I can fix this?
Whenever I try to visit the single products url, I get the error from getStaticPaths when trying to generate all the possible values for parameters in dynamic routes ahead of time when the website is being built.
Thank you in advance for any tip that could cause this. I tried alot of things but cant figure it out yet.
2
Answers
I fixed it by destructuring the value returned from the query in
getStaticPaths
.I got same error back then and that is natural you have to keep learning let me give you a hand in this
and based on error message indicates that
paths
values which are returend bygetStaticPaths
is not in correct formats if i say specifically it should be an array of objects with shape like{ params: [key: string]: string }
but code is returning array of objects with the shape like{ id: string }
but dont worry you can fix this by
map
function ingetStaticPaths
to return objects in correct shapes as in my local server codes are working fineyou have to use this variable are paths
this way you can create an array of objects with their correct
params
property that contains an object with respectiveid
if that helped you . you can upvote this answer to help other junior developers like you 🙂