Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
173
rated 0 times [  178] [ 5]  / answers: 1 / hits: 20139  / 3 Years ago, mon, february 15, 2021, 12:00:00

I don't understand these errors when I export as production npm run build , but when I test npm run dev it works just fine. I use getStaticProps and getStaticPath fetch from an API route.


First when I npm run build


FetchError: invalid json response body at https://main-website-next.vercel.app/api/products reason: Unexpected token T in JSON at position
0
at D:zummonMain Websitemain-website-nextnode_modulesnode-fetchlibindex.js:272:32
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async getStaticPaths (D:zummonMain Websitemain-website-next.nextserverpagesproduct[slug].js:1324:18)
at async buildStaticPaths (D:zummonMain Websitemain-website-nextnode_modulesnextdistbuildutils.js:16:80)
at async D:zummonMain Websitemain-website-nextnode_modulesnextdistbuildutils.js:26:612
at async D:zummonMain Websitemain-website-nextnode_modulesnextdistbuildtracer.js:1:1441 {
type: 'invalid-json'
}

pagesproduct[slug]


import { assetPrefix } from '../../next.config'

export default function Page(){...}

export const getStaticProps = async ({ params: { slug }, locale }) => {
const res = await fetch(`${assetPrefix}/api/products/${slug}`)
const result = await res.json()
const data = result.filter(item => item.locale === locale)[0]
const { title, keywords, description } = data
return {
props: {
data,
description,
keywords,
title
}
}
}

export const getStaticPaths = async () => {
const res = await fetch(`${assetPrefix}/api/products`)
const result = await res.json()
const paths = result.map(({ slug, locale }) => ({ params: { slug: slug }, locale }))
return {
fallback: true,
paths,
}
}

next.config.js


const isProd = process.env.NODE_ENV === 'production'

module.exports = {
assetPrefix: isProd ? 'https://main-website-next.vercel.app' : 'http://localhost:3000',
i18n: {
localeDetection: false,
locales: ['en', 'th'],
defaultLocale: 'en',
}
}

API routes


// pages/api/products/index.js
import data from '../../../data/products'
export default (req, res) => {
res.status(200).json(data)
}

// pages/api/products/[slug].js
import db from '../../../data/products'
export default ({ query: { slug } }, res) => {
const data = db.filter(item => item.slug === slug)
if (data.length > 0) {
res.status(200).json(data)
} else {
res.status(404).json({ message: `${slug} not found` })
}
}

// ../../../data/products (data source)
module.exports = [
{ locale: "en", slug: "google-sheets-combine-your-cashflow",
title: "Combine your cashflow",
keywords: ["Google Sheets","accounting"],
description: "...",
},
...
]

Second when I remove the production domain, I run npm run build but still get the error like


TypeError: Only absolute URLs are supported
at getNodeRequestOptions (D:zummonMain Websitemain-website-nextnode_modulesnode-fetchlibindex.js:1305:9)
at D:zummonMain Websitemain-website-nextnode_modulesnode-fetchlibindex.js:1410:19
at new Promise (<anonymous>)
at fetch (D:zummonMain Websitemain-website-nextnode_modulesnode-fetchlibindex.js:1407:9)
at getStaticPaths (D:zummonMain Websitemain-website-next.nextserverpages[slug].js:938:21)
at buildStaticPaths (D:zummonMain Websitemain-website-nextnode_modulesnextdistbuildutils.js:16:86)
at D:zummonMain Websitemain-website-nextnode_modulesnextdistbuildutils.js:26:618
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async D:zummonMain Websitemain-website-nextnode_modulesnextdistbuildtracer.js:1:1441 {
type: 'TypeError'
}

My next.config.js after remove


const isProd = process.env.NODE_ENV === 'production'

module.exports = { //remove
assetPrefix: isProd ? '' : 'http://localhost:3000',
i18n: {
localeDetection: false,
locales: ['en', 'th'],
defaultLocale: 'en',
}
}

My package.json when I npm run build script


{
"name": "main-website-next",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build && next export",
"start": "next start"
},
"dependencies": {
"next": "10.0.6",
"react": "17.0.1",
"react-dom": "17.0.1"
}
}

More From » node.js

 Answers
82

You should not call an internal API route inside getStaticProps. Instead, you can safely use your API logic directly in getStaticProps/getStaticPaths. These only happen server-side so you can write server-side code directly.



As getStaticProps runs only on the server-side, it will never run on
the client-side. It won’t even be included in the JS bundle for the
browser, so you can write direct database queries without them being
sent to browsers.


This means that instead of fetching an API route from
getStaticProps (that itself fetches data from an external source),
you can write the server-side code directly in getStaticProps.



Furthermore, your API routes are not available during build-time, as the server has not been started at that point.




Here's a small refactor of your code to address the issue.


// /pages/product/[slug]

import db from '../../../data/products'

// Remaining code..

export const getStaticProps = async ({ params: { slug }, locale }) => {
const result = db.filter(item => item.slug === slug)
const data = result.filter(item => item.locale === locale)[0]
const { title, keywords, description } = data
return {
props: {
data,
description,
keywords,
title
}
}
}

export const getStaticPaths = async () => {
const paths = db.map(({ slug, locale }) => ({ params: { slug: slug }, locale }))
return {
fallback: true,
paths,
}
}

[#50398] Thursday, January 28, 2021, 3 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
kendellc

Total Points: 84
Total Questions: 97
Total Answers: 102

Location: Moldova
Member since Sat, Aug 6, 2022
2 Years ago
;