gen:sitemap (next-page-router)
next.js page router 에서 pages 폴더 기반으로 sitemap.xml 파일을 생성합니다.
- Sitemap
- Config
- Folder Structure
sitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https:/example.com/</loc>
<priority>1</priority>
</url>
<url>
<loc>https:/example.com/comme</loc>
</url>
<url>
<loc>https:/example.com/goods</loc>
</url>
<url>
<loc>https:/example.com/payment/fail</loc>
<priority>0.5</priority>
<changefreq>hourly</changefreq>
</url>
<url>
<loc>https:/example.com/payment/success</loc>
<priority>0.5</priority>
<changefreq>hourly</changefreq>
</url>
<url>
<loc>https:/example.com/goods/0</loc>
<priority>0.5</priority>
</url>
<url>
<loc>https:/example.com/goods/1</loc>
<priority>0.5</priority>
</url>
<url>
<loc>https:/example.com/goods/2</loc>
<priority>0.5</priority>
</url>
<url>
<loc>https:/example.com/goods/3</loc>
<priority>0.5</priority>
</url>
...
<url>
<loc>https:/example.com/goods/98</loc>
<priority>0.5</priority>
</url>
<url>
<loc>https:/example.com/goods/99</loc>
<priority>0.5</priority>
</url>
<url>
<loc>https:/example.com/goods/review</loc>
</url>
</urlset>
tok-cli.config.ts
import { getSitemap } from '@toktokhan-dev/cli-plugin-gen-sitemap-next-page'
const config: RootConfig<{
plugins: [typeof getSitemap]
}> = {
plugins: [getSitemap],
'gen:sitemap': {
domain: 'https://example.com',
/**
* optional
*/
routeMapper: {
'/goods/[id]': ['/goods/0', '/goods/1', '/goods/2', '/goods/3', ... '/goods/99'],
},
/**
* optional
*/
priority: {
1: ['/'],
0.5: ['/payment/*', ['/goods/*', '!/goods/review']],
},
/**
* optional
*/
changefreq: {
hourly: ['/payment/*'],
},
},
}
export default config
folder-structure
pages
├── index.ts
├── _app.ts
├── _document.ts
├── comments
│ └── index.ts
├── goods
│ ├── index.ts
│ ├── [id]
│ │ └── index.ts
│ └── review
│ └── index.ts
└── payment
├── fail.ts
└── success.ts
Installation
- npm
- yarn
- pnpm
npm i -D @toktokhan-dev/cli-plugin-gen-sitemap-next-page
yarn add -D @toktokhan-dev/cli-plugin-gen-sitemap-next-page
pnpm add -D @toktokhan-dev/cli-plugin-gen-sitemap-next-page
Run Script
command 를 별도로 입력하지 않으면 대화형으로 실행되어 등록되어있는 스크립트 중 선택하여 사용이 가능합니다.
npx tokript
command 를 입력하면 해당 스크립트가 바로 실행됩니다.
npx tokript gen:sitemap
팁
자주 사용될 수 있는 스크립트는 협업간 편의성을 위해 package.json
에 등록하는걸 권장 드립니다.
package.json
{
...
"scripts": {
"gen:sitemap": "tokript gen:sitemap",
}
}
- yarn
- npm
- pnpm
yarn run gen:sitemap
npm run gen:sitemap
pnpm run gen:sitemap
Configuration
tok-cli.config.ts
에서 config 정의가 가능합니다.
tokript.config.ts
import { getSitemap } from '@toktokhan-dev/cli-plugin-gen-sitemap-next-page'
const config: RootConfig<{
plugins: [typeof getSitemap]
}> = {
plugins: [getSitemap],
'gen:sitemap': {
...
},
}
export default config
domain
- Required:
true
- Type:
string
- Default:
- Cli Option:
--domain
-d
config
tok-cli.config.ts
{
'gen:sitemap': {
domain: 'https://example.com',
...
},
}
cli
tokript gen:sitemap --domain "https://example.com"
input
- Required:
false
- Type:
string
- Default:
./src/pages
- Cli Option:
--input
-i
config
tok-cli.config.ts
{
'gen:sitemap': {
input: './src/pages',
...
},
}
cli
tokript gen:sitemap --input "./src/pages"
includes
- Required:
false
- Type:
string[]
- Default:
['**/*.{ts,tsx}']
- Cli Option:
--includes
-ic
config
tok-cli.config.ts
{
'gen:sitemap': {
includes: ['**/*.{ts,tsx}'],
...
},
}
cli
tokript gen:sitemap --includes '**/*.{ts,tsx}'
ignored
- Required:
false
- Type:
string[]
- Default:
[ '**/api/**', '**/_app.{ts,tsx}', '**/_document.{ts,tsx}', '**/_error.{ts,tsx}', ]
- Cli Option:
--ignored
-ig
config
tok-cli.config.ts
{
'gen:sitemap': {
ignored: ['**/api/**', '**/_app.{ts,tsx}', '**/_document.{ts,tsx}', '**/_error.{ts,tsx}'],
...
},
}
cli
tokript gen:sitemap --ignored '**/api/**', '**/_app.{ts,tsx}', '**/_document.{ts,tsx}', '**/_error.{ts,tsx}'
routeMapper
- Required:
false
- Type:
Partial< Record< string, | string | string[] | Promise<string | string[]> | (() => string | string[]) | (() => Promise<string | string[]>) >
- Default:
- Cli Option:
-
key 로 파일상의 route 경로를 받고, value 로 변경될 경로, 경로 배열을 받습니다.
주로 dynamic route 에 사용됩니다.
config
tok-cli.config.ts
{
'gen:sitemap': {
routeMapper: {
'/goods/[id]': ['/goods/0', '/goods/1', '/goods/2', '/goods/3', ... '/goods/99'],
}
,
...
},
}
위험
dynamic-route 는 routeMapper
에 설정되지 않으면 자동으로 sitemap 에서 제외됩니다.
eg. /goods/[id]
, /comment/[id]
, /review/[id]
Configuration for Dynamic Route
dynamic route
에 들어올 값이 정적이라면 예시처럼 직접 배열을 전달할 수 있습니다.
{
'/goods/[category]': ['/goods/food', '/goods/cloth', '/goods/electronics'],
}
하지만 dynamic route
에 들어올 값이 서버로 부터 받아야 한다면 api 호출을 통해 string 배열을 만들어 넘겨 줄 수 있습니다.
{
'/goods/[category]': async () => {
const res = await fetch('https://example.com/api/goods')
const data = await res.json()
return data.map((item) => `/goods/${item.id}`)
},
}
만약 pagination 이 적용된 api 의 모든 목록을 통해 path 를 만들어야 한다면
@toktokhan-dev/universal
의 relay
함수를 사용하여 전체 목록을 받아 올 수 있습니다.
import { relay } from '@toktokhan-dev/universal'
...
{
'/goods/[id]': relay({
initialParam: 0,
getNext: (nextParam: number) => goodsApi.list({ offset: nextParam, limit: 10 }),
getNextParams: (last) => last?.next,
selector: (pages) =>
pages.map((p) => p.data.map((id) => `/goods/${id}`)).flat(),
}),
}
changefreq
- Required:
false
- Type:
Partial<Record<Changefreq, (string | string[])[]>>
- Default:
- Cli Option:
-
changefreq:
always
, hourly
, daily
, weekly
, monthly
, yearly
, never
,
config
tok-cli.config.ts
{
'gen:sitemap': {
changefreq: {
/**
* /goods/1, /goods/2, /goods/3, ... /goods/99 처럼 모든 경로의 해당합니다.
*/
daily: ['/gooods/*'],
/**
* 배열로 넘겨진 /comments 의 경우
* /comments/1, ... /comments/99 처럼 모든 경로의 해당하지만, /comments/review 는 제외됩니다.
*/
hourly: ['/payment/*', ["/comments/*", "!/comments/review"]],
},
...
},
}
priority
- Required:
false
- Type:
Partial<Record<Changefreq, (string | string[])[]>>
- Default:
- Cli Option:
-
priority:
0 ~ 1
config
tok-cli.config.ts
{
'gen:sitemap': {
priority: {
/**
* /goods/1, /goods/2, /goods/3, ... /goods/99 처럼 모든 경로의 해당합니다.
*/
0.5: ['/gooods/*'],
/**
* 배열로 넘겨진 /comments 의 경우
* /comments/1, ... /comments/99 처럼 모든 경로의 해당하지만, /comments/review 는 제외됩니다.
*/
1: ['/payment/*', ["/comments/*", "!/comments/review"]],
},
...
},
}