Skip to content

Commit

Permalink
Merge pull request #591 from iamvishnusankar/exp/app-dir-server-sitemap
Browse files Browse the repository at this point in the history
[Feat] AppDir Support
  • Loading branch information
iamvishnusankar committed Mar 2, 2023
2 parents 5413f1b + 7dc5374 commit cf5fdec
Show file tree
Hide file tree
Showing 36 changed files with 2,531 additions and 2,085 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
platform: [ubuntu-latest, macos-latest, windows-latest]
node: ['16', '17', '18', '19']
node: ['16', '18']
runs-on: ${{ matrix.platform }}
steps:
- name: Github Checkout
Expand Down
92 changes: 83 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,24 +297,54 @@ Sitemap: https://example.com/my-custom-sitemap-3.xml
`next-sitemap` now provides two APIs to generate server side sitemaps. This will help to dynamically generate `index-sitemap`(s) and `sitemap`(s) by sourcing data from CMS or custom source.
- `getServerSideSitemapIndex`: Generates index sitemaps based on urls provided and returns `application/xml` response.
- `getServerSideSitemapIndex`: Generates index sitemaps based on urls provided and returns `application/xml` response. Supports next13+ route.{ts,js} file.
- `getServerSideSitemap`: Generates sitemap based on field entires and returns `application/xml` response.
- To continue using inside pages directory, import `getServerSideSitemapIndexLegacy` instead.
- `getServerSideSitemap`: Generates sitemap based on field entires and returns `application/xml` response. Supports next13+ route.{ts,js} file.
- To continue using inside pages directory, import `getServerSideSitemapLegacy` instead.
### Server side index-sitemaps (getServerSideSitemapIndex)
Here's a sample script to generate index-sitemap on server side. Create `pages/server-sitemap-index.xml/index.tsx` page and add the following content.
Here's a sample script to generate index-sitemap on server side.
<details>
<summary>1. Index sitemap (app directory)</summary>
Create `app/server-sitemap-index.xml/route.ts` file.
```ts
// pages/server-sitemap-index.xml/index.tsx
// app/server-sitemap-index.xml/route.ts
import { getServerSideSitemapIndex } from 'next-sitemap'

export async function GET(request: Request) {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

return getServerSideSitemapIndex([
'https://example.com/path-1.xml',
'https://example.com/path-2.xml',
])
}
```
</details>
<details>
<summary>2. Index sitemap (pages directory) (legacy)</summary>
Create `pages/server-sitemap-index.xml/index.tsx` file.
```ts
// pages/server-sitemap-index.xml/index.tsx
import { getServerSideSitemapIndexLegacy } from 'next-sitemap'
import { GetServerSideProps } from 'next'

export const getServerSideProps: GetServerSideProps = async (ctx) => {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

return getServerSideSitemapIndex(ctx, [
return getServerSideSitemapIndexLegacy(ctx, [
'https://example.com/path-1.xml',
'https://example.com/path-2.xml',
])
Expand All @@ -324,6 +354,10 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
export default function SitemapIndex() {}
```
</details>
#### Exclude server index sitemap from robots.txt
Now, `next.js` is serving the dynamic index-sitemap from `http://localhost:3000/server-sitemap-index.xml`.

List the dynamic sitemap page in `robotsTxtOptions.additionalSitemaps` and exclude this path from static sitemap list.
Expand All @@ -346,14 +380,52 @@ module.exports = {

In this way, `next-sitemap` will manage the sitemaps for all your static pages and your dynamic `index-sitemap` will be listed on robots.txt.

---

### server side sitemap (getServerSideSitemap)

Here's a sample script to generate sitemaps on server side. Create `pages/server-sitemap.xml/index.tsx` page and add the following content.
Here's a sample script to generate sitemaps on server side.
```ts
// pages/server-sitemap.xml/index.tsx
<details>
<summary>1. Sitemaps (app directory)</summary>
Create `app/server-sitemap.xml/route.ts` file.
```ts
// app/server-sitemap.xml/route.ts
import { getServerSideSitemap } from 'next-sitemap'
export async function GET(request: Request) {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

return getServerSideSitemap([
{
loc: 'https://example.com',
lastmod: new Date().toISOString(),
// changefreq
// priority
},
{
loc: 'https://example.com/dynamic-path-2',
lastmod: new Date().toISOString(),
// changefreq
// priority
},
])
}
```
</details>
<details>
<summary>2. Sitemaps (pages directory) (legacy)</summary>
Create `pages/server-sitemap.xml/index.tsx` file.
```ts
// pages/server-sitemap.xml/index.tsx
import { getServerSideSitemapLegacy } from 'next-sitemap'
import { GetServerSideProps } from 'next'

export const getServerSideProps: GetServerSideProps = async (ctx) => {
Expand All @@ -375,13 +447,15 @@ export const getServerSideProps: GetServerSideProps = async (ctx) => {
},
]

return getServerSideSitemap(ctx, fields)
return getServerSideSitemapLegacy(ctx, fields)
}

// Default export to prevent next.js errors
export default function Sitemap() {}
```
</details>
Now, `next.js` is serving the dynamic sitemap from `http://localhost:3000/server-sitemap.xml`.

List the dynamic sitemap page in `robotsTxtOptions.additionalSitemaps` and exclude this path from static sitemap list.
Expand Down
2 changes: 1 addition & 1 deletion azure-pipeline.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: 3.1$(rev:.r)
name: 4.0$(rev:.r)
trigger:
branches:
include:
Expand Down
15 changes: 15 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## 4.0.x

v4.0.x added support for next13.2+ `appDir` via [Custom Route Handlers](https://nextjs.org/blog/next-13-2#custom-route-handlers)

#### API Changes

Generating dynamic/server-side sitemaps

- `getServerSideSitemapIndex`: Generates index sitemaps based on urls provided and returns application/xml response. Supports next13+ route.{ts,js} file.

- To continue using inside pages directory, import `getServerSideSitemapIndexLegacy` instead.

- `getServerSideSitemap`: Generates sitemap based on field entires and returns application/xml response. Supports next13+ route.{ts,js} file.

- To continue using inside pages directory, import `getServerSideSitemapLegacy` instead.
6 changes: 3 additions & 3 deletions examples/amp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@
"postbuild": "next-sitemap"
},
"dependencies": {
"@types/react-dom": "^18.0.10",
"next": "^13.2.1",
"@types/react-dom": "^18.0.11",
"next": "^13.2.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/react": "^18.0.27",
"@types/react": "^18.0.28",
"next-sitemap": "*"
}
}
12 changes: 12 additions & 0 deletions examples/app-dir/app/(sitemaps)/server-sitemap-index.xml/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { getServerSideSitemapIndex } from 'next-sitemap'

export async function GET(request: Request) {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

return getServerSideSitemapIndex([
'https://example.com/path-1.xml',
'https://example.com/path-2.xml',
])
}
22 changes: 22 additions & 0 deletions examples/app-dir/app/(sitemaps)/server-sitemap.xml/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { getServerSideSitemap } from 'next-sitemap'

export async function GET(request: Request) {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

return getServerSideSitemap([
{
loc: 'https://example.com',
lastmod: new Date().toISOString(),
// changefreq
// priority
},
{
loc: 'https://example.com/dynamic-path-2',
lastmod: new Date().toISOString(),
// changefreq
// priority
},
])
}
8 changes: 5 additions & 3 deletions examples/app-dir/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
"postbuild": "next-sitemap"
},
"dependencies": {
"@types/react-dom": "^18.0.10",
"next": "^13.2.1",
"@types/react-dom": "^18.0.11",
"next": "^13.2.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@corex/workspace": "^4.0.37",
"@types/react": "^18.0.27",
"next-sitemap": "*"
"next-sitemap": "*",
"turbo": "^1.8.3"
}
}
6 changes: 3 additions & 3 deletions examples/basic/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "with-next-sitemap",
"name": "basic",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
Expand All @@ -11,8 +11,8 @@
"postbuild": "next-sitemap"
},
"dependencies": {
"@types/react-dom": "^18.0.10",
"next": "^13.2.1",
"@types/react-dom": "^18.0.11",
"next": "^13.2.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
4 changes: 2 additions & 2 deletions examples/basic/pages/server-sitemap-index.xml/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-empty-function */
import { getServerSideSitemapIndex } from 'next-sitemap'
import { getServerSideSitemapIndexLegacy } from 'next-sitemap'
import { GetServerSideProps } from 'next'

export const getServerSideProps: GetServerSideProps = async (ctx) => {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

return getServerSideSitemapIndex(ctx, [
return getServerSideSitemapIndexLegacy(ctx, [
'https://example.com/path-1.xml',
'https://example.com/path-2.xml',
])
Expand Down
4 changes: 2 additions & 2 deletions examples/basic/pages/server-sitemap.xml/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-empty-function */
import { getServerSideSitemap } from 'next-sitemap'
import { getServerSideSitemapLegacy } from 'next-sitemap'
import { GetServerSideProps } from 'next'

export const getServerSideProps: GetServerSideProps = async (ctx) => {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

return getServerSideSitemap(ctx, [
return getServerSideSitemapLegacy(ctx, [
{
loc: 'https://example.com',
lastmod: new Date().toISOString(),
Expand Down
6 changes: 3 additions & 3 deletions examples/commonjs/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "with-commonjs",
"name": "commonjs",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
Expand All @@ -10,8 +10,8 @@
"postbuild": "next-sitemap"
},
"dependencies": {
"@types/react-dom": "^18.0.10",
"next": "^13.2.1",
"@types/react-dom": "^18.0.11",
"next": "^13.2.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
4 changes: 2 additions & 2 deletions examples/commonjs/pages/server-sitemap-index.xml/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-empty-function */
import { getServerSideSitemapIndex } from 'next-sitemap'
import { getServerSideSitemapIndexLegacy } from 'next-sitemap'
import { GetServerSideProps } from 'next'

export const getServerSideProps: GetServerSideProps = async (ctx) => {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

return getServerSideSitemapIndex(ctx, [
return getServerSideSitemapIndexLegacy(ctx, [
'https://example.com/path-1.xml',
'https://example.com/path-2.xml',
])
Expand Down
4 changes: 2 additions & 2 deletions examples/commonjs/pages/server-sitemap.xml/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-empty-function */
import { getServerSideSitemap } from 'next-sitemap'
import { getServerSideSitemapLegacy } from 'next-sitemap'
import { GetServerSideProps } from 'next'

export const getServerSideProps: GetServerSideProps = async (ctx) => {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

return getServerSideSitemap(ctx, [
return getServerSideSitemapLegacy(ctx, [
{
loc: 'https://example.com',
lastmod: new Date().toISOString(),
Expand Down
4 changes: 2 additions & 2 deletions examples/custom-config-file/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
"postbuild": "next-sitemap --config=awesome-sitemap.config.js"
},
"dependencies": {
"@types/react-dom": "^18.0.10",
"next": "^13.2.1",
"@types/react-dom": "^18.0.11",
"next": "^13.2.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-empty-function */
import { getServerSideSitemapIndex } from 'next-sitemap'
import { getServerSideSitemapIndexLegacy } from 'next-sitemap'
import { GetServerSideProps } from 'next'

export const getServerSideProps: GetServerSideProps = async (ctx) => {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

return getServerSideSitemapIndex(ctx, [
return getServerSideSitemapIndexLegacy(ctx, [
'https://example.com/path-1.xml',
'https://example.com/path-2.xml',
])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
/* eslint-disable @typescript-eslint/no-empty-function */
import { getServerSideSitemap } from 'next-sitemap'
import { getServerSideSitemapLegacy } from 'next-sitemap'
import { GetServerSideProps } from 'next'

export const getServerSideProps: GetServerSideProps = async (ctx) => {
// Method to source urls from cms
// const urls = await fetch('https//example.com/api')

return getServerSideSitemap(ctx, [
return getServerSideSitemapLegacy(ctx, [
{
loc: 'https://example.com',
lastmod: new Date().toISOString(),
Expand Down
Loading

0 comments on commit cf5fdec

Please sign in to comment.