admin 管理员组文章数量: 1086019
I'm wondering if the following scenario is possible with serverless (deployed on Vercel) Next JS:
I have a route /product/[id].tsx
when you send a request with the header Accept: text/html
, I would like it to go through the normal Next JS flow with a React page. But, when a request is given with Accept: application/json
, I would like it to return the JSON representation.
I have acplished it by using some custom middleware I wrote for Express (see below), but I would also like to deploy it on Vercel, and Vercel is not designed to work with a custom Express implementation.
So the question is, is it possible to do this in a serverless environment? Could one of the Next JS React pages return pure JSON, or could you return React from a Next JS Api route? Or is there another way to acplish this?
server.ts
import express, { Request, Response } from "express";
import next from 'next'
import { parse } from 'url'
const port = parseInt(process.env.PORT || "3000", 10);
const dev = process.env.NODE_ENV !== "production";
async function run(): Promise<void> {
const app = express();
const nextApp = next({ dev })
const nextHandler = nextApp.getRequestHandler()
await nextApp.prepare()
app.use((req, res) => {
res.format({
"text/html": async (req, res) => {
const parsedUrl = parse(req.url!, true)
await this.handler(req, res, parsedUrl)
},
"application/json": async (req, res) => {
res.json({
"dummy": "data"
})
}
})
});
app.listen(port, () => {
console.log(
`> Server listening at http://localhost:${port} as ${
dev ? "development" : process.env.NODE_ENV
}`
);
});
}
run()
I'm wondering if the following scenario is possible with serverless (deployed on Vercel) Next JS:
I have a route /product/[id].tsx
when you send a request with the header Accept: text/html
, I would like it to go through the normal Next JS flow with a React page. But, when a request is given with Accept: application/json
, I would like it to return the JSON representation.
I have acplished it by using some custom middleware I wrote for Express (see below), but I would also like to deploy it on Vercel, and Vercel is not designed to work with a custom Express implementation.
So the question is, is it possible to do this in a serverless environment? Could one of the Next JS React pages return pure JSON, or could you return React from a Next JS Api route? Or is there another way to acplish this?
server.ts
import express, { Request, Response } from "express";
import next from 'next'
import { parse } from 'url'
const port = parseInt(process.env.PORT || "3000", 10);
const dev = process.env.NODE_ENV !== "production";
async function run(): Promise<void> {
const app = express();
const nextApp = next({ dev })
const nextHandler = nextApp.getRequestHandler()
await nextApp.prepare()
app.use((req, res) => {
res.format({
"text/html": async (req, res) => {
const parsedUrl = parse(req.url!, true)
await this.handler(req, res, parsedUrl)
},
"application/json": async (req, res) => {
res.json({
"dummy": "data"
})
}
})
});
app.listen(port, () => {
console.log(
`> Server listening at http://localhost:${port} as ${
dev ? "development" : process.env.NODE_ENV
}`
);
});
}
run()
Share
Improve this question
asked Jul 10, 2020 at 18:20
jaxoncreedjaxoncreed
1,1282 gold badges14 silver badges25 bronze badges
1 Answer
Reset to default 8Thanks to @timneutkens (Lead engineer for NextJS) on Twitter we have our answer. It is possible. You use getServerSideProps
and perform everything you want to the res
object there. Just be sure to end it with .end
so it skips the react rendering phase.
I've made a sample repo for the code here: https://github./jaxoncreed/nextjs-content-type-test
And here's the page that matters:
import Head from 'next/head'
export default function Home() {
return (
<div className="container">
<Head>
<title>Create Next App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<h1>Test App</h1>
</main>
</div>
)
}
export async function getServerSideProps({ req, res }) {
if (req.headers.accept === "application/json") {
res.setHeader('Content-Type', 'application/json')
res.write(JSON.stringify({ "dummy": "data" }))
res.end()
}
return {
props: {}, // will be passed to the page ponent as props
}
}
本文标签: javascriptDifferent ContentTypes on the same route with Serverless Next JSStack Overflow
版权声明:本文标题:javascript - Different Content-Types on the same route with Serverless Next JS - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/p/1744090359a2531917.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论