Reputation: 2891
I've built a personal website using Next.js, and now I want to deploy it on Internet.
I followed a tutorial and it told me to create a config under project_root/config/index.js
and the content is like:
const dev = process.env.NODE_ENV !== "production"
export const server = dev? "http://localhost:3000": "http://<the_ip_of_my_server>"
The constant server
is used in the file project_root/pages/article/[id]/index.js
, as shown below.
const article = ({article}) => {
return <>
<Meta title={article.title} description={article.excerpt}/>
<h1>{article.title}</h1>
<p>{article.body}</p>
<br/>
<Link href="/">Go Back</Link>
</>
};
export const getStaticProps = async(context) => {
const res = await fetch(`${server}/api/articles/${context.params.id}`)
const article = await res.json()
return {
props: {
article
}
}
}
export const getStaticPaths = async() => {
const res = await fetch(`${server}/api/articles`)
const articles = await res.json()
const ids = articles.map(article => article.id)
const paths = ids.map(id =>
({
params: {
id: id.toString()
}
})
)
return {
paths,
fallback: false
}
}
Say now I'm using ssh
to connect to the server, then I run into the following errors:
npm run build
it says:
> Build error occurred
FetchError: request to http://<the_ip_of_my_server>:3000/api/articles failed, reason: connect ECONNREFUSED <the_ip_of_my_server>:3000
at ClientRequest.<anonymous> (/root/apps/my_project/node_modules/node-fetch/lib/index.js:1461:11)
at ClientRequest.emit (node:events:394:28)
at Socket.socketErrorListener (node:_http_client:447:9)
at Socket.emit (node:events:394:28)
at emitErrorNT (node:internal/streams/destroy:193:8)
at emitErrorCloseNT (node:internal/streams/destroy:158:3)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
type: 'system',
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED'
}
Since now I'm on the server, so it seems like I just have to use export const server = "http://localhost:3000"
?npm run dev
, then it works. But is this still a site run in "production"?getStaticProps
and getStaticPaths
, what I want is to build (so an project_root/out/
folder will be created) to project and serving the static files in the out/
folder, how to achieve this? Is this a correct way to serve a static website using next.js?This is part of my package.json
:
"scripts": {
"dev": "next dev",
"build": "next build && next export",
"start": "next start",
"lint": "next lint"
},
Upvotes: 0
Views: 103
Reputation: 2891
I also found myself an answer from the official vercel/next.js dicussion on GitHub, where @jamesmosier answered on on Jun 24, 2020:
The reason it is failing is because
http://localhost:3000/api/data
is not online when you are running your build.Instead of trying to call an API route in
getStaticProps
you should just put your logic directly in thegetStaticProps
function.Or if you are just getting your data from a static file (i.e.
import { data } from '../../data'
) just import that in yourpages/sales/[category].js
page and then use it ingetStaticProps
. Next will eliminate that code from any client side bundles as long as you only use it withingetStaticProps
.// ...all of your other imports... import { data } from '../../data' export async function getStaticProps({ params }) { return { props: { params, data } } } // ...your other code...
Upvotes: 0
Reputation: 18476
It is not allowed to fetch from the same application API route during build process because your api or server is not even running yet.
Although you can just import your api handler directly to your page code and use it inside getStaticProps
or getStaticPaths
. It won't go into client bundle anyway
Read the notes under this section in the docs
Upvotes: 1