Can't deploy next app
Answered
Masai Lion posted this in #help-forum
Masai LionOP
So i have this project: https://github.com/Felopater-Melika/Astral-Store
I am trying to deploy it but i think there is a problem in the page.tsx
i get this error:
I am trying to deploy it but i think there is a problem in the page.tsx
i get this error:
SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse (<anonymous>)
at parseJSONFromBytes (node:internal/deps/undici/undici:6498:19)
at successSteps (node:internal/deps/undici/undici:6472:27)
at node:internal/deps/undici/undici:1145:60
at node:internal/process/task_queues:140:7
at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error
SyntaxError: Unexpected token < in JSON at position 0
at JSON.parse (<anonymous>)
at parseJSONFromBytes (node:internal/deps/undici/undici:6498:19)
at successSteps (node:internal/deps/undici/undici:6472:27)
at node:internal/deps/undici/undici:1145:60
at node:internal/process/task_queues:140:7
at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
- info Generating static pages (4/4)
> Export encountered errors on following paths:
/page: /
 ELIFECYCLE  Command failed with exit code 1.
Error: Command "pnpm run build" exited with 1
BUILD_UTILS_SPAWN_1: Command "pnpm run build" exited with 1Answered by DirtyCajunRice | AppDir
my suggestion is to change the way you are doing your logic
49 Replies
Masai LionOP
here is the log of build on my device:
> next-template@0.0.2 build C:\Users\philo\projects\Astral-Store
> next build
- info Loaded env from C:\Users\philo\projects\Astral-Store\.env.local
- info Creating an optimized production build
- info Compiled successfully
- info Linting and checking validity of types
- info Collecting page data
- info Generating static pages (4/4)
- info Finalizing page optimization
Route (app) Size First Load JS
┌ ○ / 0 B 0 B
â”” â—‹ /api/items 0 B 0 B
+ First Load JS shared by all 85.9 kB
├ chunks/106-d4a3cb813406ce7d.js 25.3 kB
├ chunks/58b30e71-cd52d4eb5faa369d.js 50.5 kB
├ chunks/798-41b1d96d0c1cde1a.js 8.19 kB
├ chunks/main-app-bbe35e5a4bef5747.js 215 B
â”” chunks/webpack-cf3820b6dd6f5e92.js 1.74 kB
Route (pages) Size First Load JS
─ ○ /404 182 B 74.9 kB
+ First Load JS shared by all 74.7 kB
├ chunks/framework-510ec8ffd65e1d01.js 45 kB
├ chunks/main-a5126d5d6f29e0b5.js 27.7 kB
├ chunks/pages/_app-cb21f3cd47a92abc.js 194 B
â”” chunks/webpack-cf3820b6dd6f5e92.js 1.74 kB
â—‹ (Static) automatically rendered as static HTML (uses no initial props)@DirtyCajunRice | AppDir looks like its trying to static compile a page that makes an api call and the api is responding with invalid json
Masai LionOP
yeah i logged the json in the api route and it works fine
everything is also working fine in development too
@Masai Lion everything is also working fine in development too
that doesnt matter 🙂
Masai LionOP
😂
is the api route also nextjs?
Masai LionOP
yes
so the page is calling back to /api?
Masai LionOP
it's basically extracting the logic of fetching products from shopify
@DirtyCajunRice | AppDir so the page is calling back to /api?
Masai LionOP
yes
is the page a client component?
Masai LionOP
const response = await fetch(
{ next: { revalidate: 20 } }
);
${
process.env.VERCEL_URL ? process.env.VERCEL_URL : 'http://localhost:3000'
}/api/items,{ next: { revalidate: 20 } }
);
@DirtyCajunRice | AppDir is the page a client component?
Masai LionOP
no it's server
so there are multiple issues there
Masai LionOP
but i just changed it to client just to see if it being server component is the issue and still got this
TypeError: Failed to parse URL from astral-store-philo-l826er2r1-felopater-melika.vercel.app/api/items
at new Request (node:internal/deps/undici/undici:7004:19)
at r (/vercel/path0/.next/server/chunks/950.js:46244:65)
at doOriginalFetch (/vercel/path0/node_modules/next/dist/server/lib/patch-fetch.js:273:24)
at /vercel/path0/node_modules/next/dist/server/lib/patch-fetch.js:392:20 {
[cause]: TypeError [ERR_INVALID_URL]: Invalid URL
at new NodeError (node:internal/errors:399:5)
at URL.onParseError (node:internal/url:566:9)
at new URL (node:internal/url:646:5)
at new Request (node:internal/deps/undici/undici:7002:25)
at r (/vercel/path0/.next/server/chunks/950.js:46244:65)
at doOriginalFetch (/vercel/path0/node_modules/next/dist/server/lib/patch-fetch.js:273:24)
at /vercel/path0/node_modules/next/dist/server/lib/patch-fetch.js:392:20 {
input: 'astral-store-philo-l826er2r1-felopater-melika.vercel.app/api/items',
code: 'ERR_INVALID_URL'
}
}
Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error
TypeError: Failed to parse URL from astral-store-philo-l826er2r1-felopater-melika.vercel.app/api/items
at new Request (node:internal/deps/undici/undici:7004:19)
at r (/vercel/path0/.next/server/chunks/950.js:46244:65)
at doOriginalFetch (/vercel/path0/node_modules/next/dist/server/lib/patch-fetch.js:273:24)
at /vercel/path0/node_modules/next/dist/server/lib/patch-fetch.js:392:20
- info Generating static pages (4/4)
> Export encountered errors on following paths:
/page: /
 ELIFECYCLE  Command failed with exit code 1.
Error: Command "pnpm run build" exited with 1
BUILD_UTILS_SPAWN_1: Command "pnpm run build" exited with 11. you dont need hostname for fetch
2. server components dont need to call api
its already on the server
does that make sense?
Masai LionOP
yeah i am just extracting the logic i guess
because it's a gql request and i have to use the fetch function instead of graphql request
import { NextResponse } from 'next/server';
import { gql, request } from 'graphql-request';
const getProducts = async (): Promise<any> => {
const url = `https://${process.env.STORE_NAME}.myshopify.com/api/2023-04/graphql.json`;
const headers = {
'X-Shopify-Storefront-Access-Token': process.env
.X_SHOPIFY_ACCESS_TOKEN as string,
};
const query = gql`
query ProductsQuery {
collections(
first: 3
query: "title:solars OR title:galaxies OR title:planets"
) {
edges {
node {
title
products(first: 10) {
edges {
node {
id
title
description
variants(first: 1) {
edges {
node {
price {
amount
}
}
}
}
images(first: 1) {
edges {
node {
url
}
}
}
}
}
}
}
}
}
}
`;
return await request(url, query, undefined, headers);
};
export async function GET() {
try {
const { collections } = await getProducts();
const solars = collections.edges
.find(({ node }: any) => node.title.toLowerCase() === 'solars')
.node.products.edges.map(({ node }: any) => node);
const galaxies = collections.edges
.find(({ node }: any) => node.title.toLowerCase() === 'galaxies')
.node.products.edges.map(({ node }: any) => node);
const planets = collections.edges
.find(({ node }: any) => node.title.toLowerCase() === 'planets')
.node.products.edges.map(({ node }: any) => node);
return NextResponse.json({
products: { solars,
galaxies,
planets,
},
});
} catch (error) {
console.error(error);
NextResponse.json({ error: 'Failed to fetch products.tsx' });
}
}if you are calling for data from a client component, yes you need host and yes you can call /api. If its a server component you should be getting the data directly
do you plan to call the api route from things other than the app itself?
Masai LionOP
no it's just from the page.tsx then i give everything to a redux store
import { setGalaxies, setPlanets, setSolars } from '@/store/productsSlice';
import { store } from '@/store/store';
import Preloader from '@/components/preloader';
import Products from '@/components/products';
import Providers from '@/components/providers';
const processDataAndDispatch = (
data: any,
category: any,
dispatchAction: any
) => {
const processedData = data.products[category].map((item: any) => {
return {
id: item.id,
title: item.title,
description: item.description,
price: item.variants.edges[0].node.price.amount,
image: item.images.edges[0].node.url,
};
});
store.dispatch(dispatchAction(processedData));
};
export default async function Page() {
const response = await fetch('/api/items', { next: { revalidate: 20 } });
const data = await response.json();
processDataAndDispatch(data, 'planets', setPlanets);
processDataAndDispatch(data, 'solars', setSolars);
processDataAndDispatch(data, 'galaxies', setGalaxies);
const products: any = store.getState().products;
const planets: any = store.getState().products.planets;
const solars: any = store.getState().products.solars;
const galaxies: any = store.getState().products.galaxies;
const allProducts: any = Object.values(products).flatMap(
(category: any) => category
);
return (
<Providers>
<Preloader
products={allProducts}
planets={planets}
solars={solars}
galaxies={galaxies}
/>
<Products products={allProducts} />
</Providers>
);
}the preloader stores the data for the client side
the products component basically takes the products and displays them and then if i decide to filter it displays from redux store
the products component basically takes the products and displays them and then if i decide to filter it displays from redux store
my suggestion is to change the way you are doing your logic
Answer
remove the api route completely
convert it to a regular function
dont use redux for storing the data… its not needed
filter the result and display it based on the filters
@DirtyCajunRice | AppDir dont use redux for storing the data… its not needed
Masai LionOP
i know i am just trying to learn to work with it
also the cart i think i need a way to store the state for that right?
also the cart i think i need a way to store the state for that right?
@Masai Lion i know i am just trying to learn to work with it
also the cart i think i need a way to store the state for that right?
Yeah. You may need redux for that, but not for ALL the items. Thats just bloaty heh
@DirtyCajunRice | AppDir Yeah. You may need redux for that, but not for ALL the items. Thats just bloaty heh
Masai LionOP
ikr zustand does the job too but i am trying to learn with redux i guess and i switched to redux tbh becuase i saw this video
https://www.youtube.com/watch?v=dRLjoT4r-jc&t=1291s
i had to watch it 5 times just to figure out how to server side render the products and also have them in redux and be interactive 😂
https://www.youtube.com/watch?v=dRLjoT4r-jc&t=1291s
i had to watch it 5 times just to figure out how to server side render the products and also have them in redux and be interactive 😂
@Masai Lion ikr zustand does the job too but i am trying to learn with redux i guess and i switched to redux tbh becuase i saw this video
https://www.youtube.com/watch?v=dRLjoT4r-jc&t=1291s
i had to watch it 5 times just to figure out how to server side render the products and also have them in redux and be interactive 😂
I was a big proponent of redux until i moved to nextjs. now i only use zustand
Masai LionOP
anyway I appreciate your help so much I will extract the api route logic to the page component then hopefully it's solved
@DirtyCajunRice | AppDir I was a big proponent of redux until i moved to nextjs. now i only use zustand
Masai LionOP
why not redux? isn't it more robust? also why not something like recoil or jotai?
@Masai Lion why not redux? isn't it more robust? also why not something like recoil or jotai?
zustand and redux are almost identical in features.
Masai LionOP
just less boilerplate?
exactly
but use what you like. its not like one is “wrongâ€
just preference 🙂
@DirtyCajunRice | AppDir just preference 🙂
Masai LionOP
Yup
@Masai Lion Yup
make sure to mark answered if you are good to go so people dont need to re-check the question
@DirtyCajunRice | AppDir make sure to mark answered if you are good to go so people dont need to re-check the question
Masai LionOP
Got it that worked thank you so much for your help sirhttps://astral-store.vercel.app/
wait the bot is malfunctioning