Trouble with deploying
Answered
Argente Brun posted this in #help-forum
Argente BrunOP
Hi everyone! Im new at next. I'm trying to deploy project with route handlers on vercel.
PRODUCTION_LINK="https://impilo.vercel.app"
API_LINK="http://impilomedicalsystems.co.za"
Im getting error
Help me to fix this please
import ProductsPageScene from "@/scenes/ProductsPageScene";
import { env } from "process";
const getProducts = async () => {
try {
if (env.PRODUCTION_LINK) {
const res = await fetch(env.PRODUCTION_LINK + `/api/products`);
const { data } = await res.json();
return data;
}
} catch (err) {
throw new Error(`ERROR: ${err}`);
}
};
const ProductsPage = async () => {
const products = await getProducts();
return <ProductsPageScene products={products} />;
};
export default ProductsPage;
PRODUCTION_LINK="https://impilo.vercel.app"
API_LINK="http://impilomedicalsystems.co.za"
import { NextResponse } from "next/server";
import { env } from "process";
export async function GET() {
const res = await fetch(`${env.API_LINK}/wp-json/xlsx/v1/computer`);
const data = await res.json();
return NextResponse.json({ data });
}
Im getting error
Error occurred prerendering page "/products". 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:6662:19)
at successSteps (node:internal/deps/undici/undici:6636:27)
at node:internal/deps/undici/undici:1236:60
at node:internal/process/task_queues:140:7
at AsyncResource.runInAsyncScope (node:async_hooks:203: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 (10/10)
> Export encountered errors on following paths:
/products/page: /products
Help me to fix this please
Answered by risky
well the original thing is that you have to:
* look at code for
* move it out to a "utils" or smth file
* import that function to the api route and use normally
* import into server component and use
* look at code for
api/products
* move it out to a "utils" or smth file
* import that function to the api route and use normally
* import into server component and use
93 Replies
Argente BrunOP
I tryed to remove production_link. It didn't help at all
instead of res.json, can you do res.text and console.log the value (ti may show the error better)
Argente BrunOP
I'm getting TS error. Because data provides array of objects
i just meant as a tempory thing, just to show the error, not actualy to mess with the code
like just return after you get the value,
as your error looks like it would be HTML, but we can't see the full error here (from your api)
Argente BrunOP
import ProductsPageScene from "@/scenes/ProductsPageScene";
import { env } from "process";
const getProducts = async () => {
try {
if (env.PRODUCTION_LINK) {
const res = await fetch(env.PRODUCTION_LINK + `/api/products`);
console.log(await res.text());
// const { data } = await res.json();
// return data;
}
} catch (err) {
throw new Error(`ERROR: ${err}`);
}
};
const ProductsPage = async () => {
const products = await getProducts();
// return <ProductsPageScene products={products} />;
return "";
};
export default ProductsPage;
ye just try that
Argente BrunOP
<!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/_next/static/chunks/webpack-4ea4d72d9fb1d23a.js" defer=""></script><script
defer=""></script><script src="/_next/static/chunks/main-6407795f441898e6.js" defer=""></script><script src="/_next/static/chunks/pages/_app-52924524f99094ab.js" defer=""></script><script src="/_next/static/chunks/pages/_error-c92d5c4bb2b49926.js" defer=""></script><script src="/_next/static/-_4cDkHYQTvEogjyKcRKK/_buildManifest.js" defer=""></script><script src="/_next/static/-_4cDkHYQTvEogjyKcRKK/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji";height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"-_4cDkHYQTvEogjyKcRKK","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
hmm a 404 page
Argente BrunOP
I'm getting this because production_link is wrong on localhost
ahhh, you should fix it then
Argente BrunOP
import ProductsPageScene from "@/scenes/ProductsPageScene";
import { env } from "process";
const getProducts = async () => {
try {
if (env.PRODUCTION_LINK) {
const res = await fetch(env.LOCALHOST + `/api/products`);
console.log(await res.text());
// const { data } = await res.json();
// return data;
}
} catch (err) {
throw new Error(`ERROR: ${err}`);
}
};
const ProductsPage = async () => {
const products = await getProducts();
// return <ProductsPageScene products={products} />;
return "";
};
export default ProductsPage;
{"data":[{"ID":6339,"post_author":"1","post_date":"2023-09-25 16:33:50","post_date_gmt":"2023-09-25 14:33:50","post_content":"","post_title":"Chison SonoAir 30","post_excerpt":"","post_status":"publish","comment_status":"closed","ping_status":"closed","post_password":"","post_name":"chison-sonoair-30","to_ping":"","pinged":"","post_modified":"2023-09-25 16:33:50","post_modified_gmt":"2023-09-25 14:33:50","post_content_filtered":"","post_parent":0,"guid":"https://impilomedicalsystems.co.za/computer/6339/","menu_order":0,"post_type":"computer","post_mime_type":"","comment_count":"0","filter":"raw","meta_code":"SA30","meta_price":"88088","meta_description":"Portable colour doppler unit with Convex and Linear Probes","meta_unitType":"portable","meta_images":["https://impilomedicalsystems.co.za/wp-content/uploads/2023/10/E1-3.png"],"meta_accessorys":[{"ID":6269,"post_author":"1","post_date":"2023-09-16 16:38:55","post_date_gmt":"2023-09-16 14:38:55","post_content":"","post_title":"Black and white thermal ultrasound printer","post_excerpt":"","post_status":"publish","comment_status":"closed","ping_status":"closed","post_password":"","
so is the api the same server as nextjs?
Argente BrunOP
it's quite big
yeah that looks good, so now go back to your other code
Argente BrunOP
import ProductsPageScene from "@/scenes/ProductsPageScene";
import { env } from "process";
const getProducts = async () => {
try {
if (env.PRODUCTION_LINK) {
const res = await fetch(env.LOCALHOST + `/api/products`);
// console.log(await res.text());
const { data } = await res.json();
return data;
}
} catch (err) {
throw new Error(`ERROR: ${err}`);
}
};
const ProductsPage = async () => {
const products = await getProducts();
// return <ProductsPageScene products={products} />;
return "";
};
export default ProductsPage;
like this?
like if the api is running on the same server and requesting server component, you should just follow: https://nextjs-faq.com/fetch-api-in-rsc
Argente BrunOP
Now its wrong link
http://localhost:3000/undefined/api/products
BUT in console im getting correct data
http://localhost:3000/undefined/api/products
BUT in console im getting correct data
intresting...
Argente BrunOP
Why??? It's too hard
But I'm getting data
o.O so it doesn't work?
Argente BrunOP
It's working on my machine, but on vercel don't
deploy error
Error: ERROR: TypeError: Failed to parse URL from /api/products
at getProducts (/vercel/path0/.next/server/app/products/page.js:541:15)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async ProductsPage (/vercel/path0/.next/server/app/products/page.js:545:22)
Error occurred prerendering page "/products". Read more: https://nextjs.org/docs/messages/prerender-error
Error: ERROR: TypeError: Failed to parse URL from /api/products
at getProducts (/vercel/path0/.next/server/app/products/page.js:541:15)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async ProductsPage (/vercel/path0/.next/server/app/products/page.js:545:22)
so are you sending using relative url for fetch on server side? (ie not https://)
Argente BrunOP
You mean In route.ts?
Or in Page
like how are you using the route
Argente BrunOP
in documentation was example
You create route.ts, describe GET or somethink Method
then
In page I'm trying to get this GET method from server api
fetch("http://localhost:3000/api/products")
It's working localy
But it doesn't on vercel
You create route.ts, describe GET or somethink Method
then
In page I'm trying to get this GET method from server api
fetch("http://localhost:3000/api/products")
It's working localy
But it doesn't on vercel
but is
fetch("http://localhost:3000/api/products")
done in a client or server component?Argente BrunOP
My boss tells me, that i've to remove localhost. That it is useless, so i left only fetch("/api/products")
But same error
But same error
server
basicly don't need to make a route for it and just do the code
Argente BrunOP
Can i fix this without any external libs?
yes
just do the code that
/api/products
has, but without fetchingArgente BrunOP
without fetching?? I don't understand how
import ProductsPageScene from "@/scenes/ProductsPageScene";
import { env } from "process";
// const getProducts = async () => {
// try {
// if (env.PRODUCTION_LINK) {
// const res = await fetch(env.LOCALHOST + `/api/products`);
// // console.log(await res.text());
// const { data } = await res.json();
// return data;
// }
// } catch (err) {
// throw new Error(`ERROR: ${err}`);
// }
// };
const ProductsPage = async () => {
const res = await fetch(`/api/products`);
const { data } = await res.json();
return <ProductsPageScene products={data} />;
return "";
};
export default ProductsPage;
I tried to do this
so, what is your code of
/api/products
... whatever it is, copy it out into another file which the api route imports and usesthen on your server compoent, also import and use
no need for fetching own api
Argente BrunOP
import ProductsPageScene from "@/scenes/ProductsPageScene";
import { env } from "process";
// const getProducts = async () => {
// try {
// if (env.PRODUCTION_LINK) {
// const res = await fetch(env.LOCALHOST + `/api/products`);
// // console.log(await res.text());
// const { data } = await res.json();
// return data;
// }
// } catch (err) {
// throw new Error(`ERROR: ${err}`);
// }
// };
const ProductsPage = async () => {
const res = await fetch(`${env.API_LINK}/wp-json/xlsx/v1/computer`);
const data = await res.json();
console.log(data);
return <ProductsPageScene products={data} />;
return "";
};
export default ProductsPage;
Like this?
so is
wp-json/xlsx/v1/computer
an external api or your own from the next server?Argente BrunOP
external
then thats good to keep
Argente BrunOP
So can you explain me what the reason of route handlers?
its your other one thats on the same nextjs server thats the issue
it just allows you to make a pathname and return any http response
whereas normal pages have to be react
so route handlers can be used for apis (but only for use of client)
Argente BrunOP
ohh wait
Route (app) Size First Load JS
┌ ○ / 2.23 kB 116 kB
├ ○ /api/products 0 B 0 B
├ λ /api/products/[id] 0 B 0 B
├ ○ /favicon.ico 0 B 0 B
├ λ /pricing/[id] 2.75 kB 133 kB
├ ○ /products 1.01 kB 132 kB
├ λ /products/[id] 24.1 kB 155 kB
├ ○ /quotes 4.46 kB 106 kB
├ ○ /roi-calculator 145 B 78.6 kB
├ ○ /training 145 B 78.6 kB
â”” â—‹ /training/in-person 145 B 78.6 kB
+ First Load JS shared by all 78.4 kB
├ chunks/596-2b60cd87bb49976c.js 25.9 kB
├ chunks/fd9d1056-158bd2a597018d29.js 50.5 kB
├ chunks/main-app-14edfdbb6ecc4631.js 215 B
â”” chunks/webpack-f1b9d75276075947.js 1.82 kB
Route (pages) Size First Load JS
─ ○ /404 182 B 75.8 kB
+ First Load JS shared by all 75.6 kB
├ chunks/framework-8883d1e9be70c3da.js 45 kB
├ chunks/main-8006ccefe3bcf712.js 28.6 kB
├ chunks/pages/_app-52924524f99094ab.js 195 B
â”” chunks/webpack-f1b9d75276075947.js 1.82 kB
λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
â—‹ (Static) automatically rendered as static HTML (uses no initial props)
There are server and client pages
and now /products is static
like /api/products
is it meant to be static? if not you can do
export const revalidate = 0
Argente BrunOP
This is catalog of products, so i guess yeeees
may be
well the original thing is that you have to:
* look at code for
* move it out to a "utils" or smth file
* import that function to the api route and use normally
* import into server component and use
* look at code for
api/products
* move it out to a "utils" or smth file
* import that function to the api route and use normally
* import into server component and use
Answer
and read the link i have sent: https://nextjs-faq.com/fetch-api-in-rsc
Argente BrunOP
Am i understood you right?
I moved out code in /api/products route.ts into utils/route.ts
And export this in page
I moved out code in /api/products route.ts into utils/route.ts
import { NextResponse } from "next/server";
import { env } from "process";
export async function GET() {
const res = await fetch(`${env.API_LINK}/wp-json/xlsx/v1/computer`);
const data = await res.json();
return NextResponse.json({ data });
}
And export this in page
import ProductsPageScene from "@/scenes/ProductsPageScene";
import { GET } from "@/utils/route";
const ProductsPage = async () => {
const res = await GET();
const { data } = await res.json();
return <ProductsPageScene products={data} />;
};
export default ProductsPage;
no...
you make your utils/route.ts file do the fetch and just return the fetched value
then in product, you would use it (no .json needed)
and then you can still have your /api/products file, just import utils/route.ts and use NextResponse on that after awaited
Argente BrunOP
i think i don't understand
You mean this?
import { NextResponse } from "next/server";
import { env } from "process";
export async function GET() {
const res = await fetch(`${env.API_LINK}/wp-json/xlsx/v1/computer`);
const data = await res.json();
return data;
}
import ProductsPageScene from "@/scenes/ProductsPageScene";
import { GET } from "@/utils/route";
const ProductsPage = async () => {
const data = await GET();
return <ProductsPageScene products={data} />;
};
export default ProductsPage;
yeah 🎉
and you can chosse a better name then get and file name
Argente BrunOP
So now i've useless route in api
Is this ok?
you can keep or remove it...
Argente BrunOP
once you test it, we will see
sorry for sounding confusing ;(
Argente BrunOP
don't sorry please... You did a great job!
Argente BrunOP
MAAAN. Im so confused. There was error in api
http instead of https
that's 404 code
o.O
Argente BrunOP
Thank you so much for your time and patience
It'll be great have more like you, Thank You!
no problem... i like helping :), also if your question is solved, can you use the mark solution option 🙂 (or tell me which message to do)
Argente BrunOP
No problem. How can i do this? I don't see it
that message i think
its mentioned in the first message by the bot, but as i have "helper role", i can do it manualy 🙂
Argente BrunOP
Okay. Take care of yourself
you too, if you have any more questions, fell free to make a new post 🙂