带有 nextjs 路由的更漂亮的 url
prettier urls with nextjs routes
我正在使用 next.js
为我的公司构建一个新的营销网站,我 运行 遇到了 URLS 的问题。本质上,我已经构建了一个自定义 API 路由来使用 Prisma 从我们的内部数据库访问数据:
getAllDealers.ts
import Cors from 'cors';
import { prisma } from 'lib/prisma';
import { NextApiResponse, NextApiRequest, NextApiHandler } from 'next';
const cors = Cors({
methods: ['GET', 'HEAD'],
});
function runMiddleware(req: NextApiRequest, res: NextApiResponse, fn: any) {
return new Promise((resolve, reject) => {
fn(req, res, (result: any) => {
if (result instanceof Error) {
return reject(result);
}
return resolve(result);
});
});
}
const getDealers: NextApiHandler = async (req: NextApiRequest, res: NextApiResponse) => {
const { method } = req;
await runMiddleware(req, res, cors);
const dealers = await prisma.crm_dealers.findMany({
where: {
active: {
not: 0,
},
},
});
switch (method) {
case 'GET':
res.status(200).send({ dealers, method: method });
break;
case 'PUT':
res.status(500).json({ message: 'sorry, we only accept GET requests', method: method });
break;
default:
res.setHeader('Allow', ['GET']);
res.status(405).end(`Method ${method} Not Allowed`);
}
};
export default getDealers;
我已经建立了一条访问个别经销商的路线:
getSingleDealer.ts
import Cors from 'cors';
import { prisma } from 'lib/prisma';
import { NextApiResponse, NextApiRequest, NextApiHandler } from 'next';
const cors = Cors({
methods: ['GET', 'HEAD'],
});
function runMiddleware(req: NextApiRequest, res: NextApiResponse, fn: any) {
return new Promise((resolve, reject) => {
fn(req, res, (result: any) => {
if (result instanceof Error) {
return reject(result);
}
return resolve(result);
});
});
}
const getDealerById: NextApiHandler = async (req: NextApiRequest, res: NextApiResponse) => {
await runMiddleware(req, res, cors);
const dealer = await prisma.crm_dealers.findUnique({
where: {
id: Number(req.query.id),
},
});
res.status(200).send({ dealer, method: req.method });
};
export default getDealerById;
我可以像这样在 getServerSideProps
中使用我的 getSingleDealer
函数:
export const getServerSideProps = async ({ params }: Params) => {
const { uid } = params;
const { dealer } = await getSingleDealer('api/dealer', uid);
return {
props: { dealer },
};
};
这很好用。不过,我需要做的是美化我的 URLS。现在,访问单个经销商页面的方法是 dealers/1
,其中 1 是经销商的 ID。我想让 URL 成为一个字符串,例如 dealers/sacramento-ca
(该位置也在 API 中提供),同时仍然基于 id
所以它正在搜索一个整数,而不是一个字符串。接下来有可能吗?
您将使用 getServerSideProps similarly to what you are doing now. To do so, you need to configure your dynamic routing 文件或文件夹名称来处理客户端中的路由,以匹配您想要的格式。
示例文件夹结构为:
pages > dealers > [dealer].tsx
= /dealers/sacramento-ca
pages > dealers > [location] > index.tsx
= /dealers/sacramento-ca
export const getServerSideProps = async ({ params }: Params) => {
const { uid } = params;
const { dealer } = await getSingleDealer('api/dealer', uid);
if (!dealer ) {
return { notFound: true }
}
return {
props: {
...dealer,
location: 'sacramento-ca', // object key must match your dynamic [folder or file's name]
},
};
};
所有动态 URL 部分都必须作为键包含在 return 中。
pages > dealers > [state] > index.tsx [city].tsx
= /dealers/ca/sacramento
return {
props: {
...dealer,
city: 'sacramento',
state: 'ca',
},
};
这里有一个article detailing what you will need to do. It's important to note that sometimes it's desirable to use a catch all route来简化搜索和深度嵌套的动态路由。
我正在使用 next.js
为我的公司构建一个新的营销网站,我 运行 遇到了 URLS 的问题。本质上,我已经构建了一个自定义 API 路由来使用 Prisma 从我们的内部数据库访问数据:
getAllDealers.ts
import Cors from 'cors';
import { prisma } from 'lib/prisma';
import { NextApiResponse, NextApiRequest, NextApiHandler } from 'next';
const cors = Cors({
methods: ['GET', 'HEAD'],
});
function runMiddleware(req: NextApiRequest, res: NextApiResponse, fn: any) {
return new Promise((resolve, reject) => {
fn(req, res, (result: any) => {
if (result instanceof Error) {
return reject(result);
}
return resolve(result);
});
});
}
const getDealers: NextApiHandler = async (req: NextApiRequest, res: NextApiResponse) => {
const { method } = req;
await runMiddleware(req, res, cors);
const dealers = await prisma.crm_dealers.findMany({
where: {
active: {
not: 0,
},
},
});
switch (method) {
case 'GET':
res.status(200).send({ dealers, method: method });
break;
case 'PUT':
res.status(500).json({ message: 'sorry, we only accept GET requests', method: method });
break;
default:
res.setHeader('Allow', ['GET']);
res.status(405).end(`Method ${method} Not Allowed`);
}
};
export default getDealers;
我已经建立了一条访问个别经销商的路线:
getSingleDealer.ts
import Cors from 'cors';
import { prisma } from 'lib/prisma';
import { NextApiResponse, NextApiRequest, NextApiHandler } from 'next';
const cors = Cors({
methods: ['GET', 'HEAD'],
});
function runMiddleware(req: NextApiRequest, res: NextApiResponse, fn: any) {
return new Promise((resolve, reject) => {
fn(req, res, (result: any) => {
if (result instanceof Error) {
return reject(result);
}
return resolve(result);
});
});
}
const getDealerById: NextApiHandler = async (req: NextApiRequest, res: NextApiResponse) => {
await runMiddleware(req, res, cors);
const dealer = await prisma.crm_dealers.findUnique({
where: {
id: Number(req.query.id),
},
});
res.status(200).send({ dealer, method: req.method });
};
export default getDealerById;
我可以像这样在 getServerSideProps
中使用我的 getSingleDealer
函数:
export const getServerSideProps = async ({ params }: Params) => {
const { uid } = params;
const { dealer } = await getSingleDealer('api/dealer', uid);
return {
props: { dealer },
};
};
这很好用。不过,我需要做的是美化我的 URLS。现在,访问单个经销商页面的方法是 dealers/1
,其中 1 是经销商的 ID。我想让 URL 成为一个字符串,例如 dealers/sacramento-ca
(该位置也在 API 中提供),同时仍然基于 id
所以它正在搜索一个整数,而不是一个字符串。接下来有可能吗?
您将使用 getServerSideProps similarly to what you are doing now. To do so, you need to configure your dynamic routing 文件或文件夹名称来处理客户端中的路由,以匹配您想要的格式。
示例文件夹结构为:
pages > dealers > [dealer].tsx
= /dealers/sacramento-ca
pages > dealers > [location] > index.tsx
= /dealers/sacramento-ca
export const getServerSideProps = async ({ params }: Params) => {
const { uid } = params;
const { dealer } = await getSingleDealer('api/dealer', uid);
if (!dealer ) {
return { notFound: true }
}
return {
props: {
...dealer,
location: 'sacramento-ca', // object key must match your dynamic [folder or file's name]
},
};
};
所有动态 URL 部分都必须作为键包含在 return 中。
pages > dealers > [state] > index.tsx [city].tsx
= /dealers/ca/sacramento
return {
props: {
...dealer,
city: 'sacramento',
state: 'ca',
},
};
这里有一个article detailing what you will need to do. It's important to note that sometimes it's desirable to use a catch all route来简化搜索和深度嵌套的动态路由。