├── .npmignore ├── index.js ├── package.json ├── LICENSE ├── utils └── paginator.js ├── CHANGELOG.md ├── generator.js └── README.md /.npmignore: -------------------------------------------------------------------------------- 1 | tests 2 | .github 3 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const generator = require('./generator'); 4 | const path = require('path'); 5 | 6 | let isRunning = false; 7 | 8 | module.exports = 9 | (sitemap = {}) => 10 | (nextConfig = {}) => 11 | Object.assign({}, nextConfig, { 12 | webpack(config, options) { 13 | const { isServer, buildId, webpack } = options; 14 | 15 | if (typeof nextConfig.webpack === 'function' && isRunning == false) { 16 | config = nextConfig.webpack(config, options) 17 | } 18 | 19 | if (isServer && isRunning == false) { 20 | isRunning = true; 21 | 22 | console.log('[Sitemap Generator]: Generating Sitemap'); 23 | 24 | if (typeof sitemap.publicPath === 'undefined') { 25 | sitemap.publicPath = path.join(options.dir, 'public'); 26 | } 27 | 28 | generator(sitemap); 29 | } 30 | 31 | 32 | return config; 33 | } 34 | }) 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@reecem/prismic-sitemap", 3 | "version": "0.5.3", 4 | "description": "Sitemap Generator for Prismic and Next.js with Minimal Configuration", 5 | "keywords": [ 6 | "javascript", 7 | "nextjs", 8 | "prismic.io", 9 | "sitemap", 10 | "sitemap generator" 11 | ], 12 | "repository": { 13 | "url": "https://github.com/reecem/prismic-sitemap" 14 | }, 15 | "main": "index.js", 16 | "dependencies": { 17 | "prismic-javascript": "^3.0.2", 18 | "sitemap": "^6.4.0" 19 | }, 20 | "devDependencies": { 21 | "cross-spawn": "^7.0.3", 22 | "jest": "^26.6.3", 23 | "next": "^13.0.5", 24 | "node-fetch": "^2.6.1", 25 | "react": "^18.2.0", 26 | "react-dom": "^18.2.0" 27 | }, 28 | "scripts": { 29 | "sitemap": "node ./index.js", 30 | "test": "PORT=4000 TEST_REPOSITORY=https://hbar.cdn.prismic.io/api/v2 jest" 31 | }, 32 | "engines": { 33 | "node": ">=12.0" 34 | }, 35 | "author": "@ReeceM", 36 | "license": "MIT" 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /utils/paginator.js: -------------------------------------------------------------------------------- 1 | const Prismic = require("prismic-javascript"); 2 | 3 | const paginator = { 4 | pageSize: 20, 5 | api: null, 6 | results: [], 7 | /** 8 | * 9 | * @param {Prismic} api prismic client 10 | * @param {Object} options {pageSize} 11 | */ 12 | init(api, options = {}) { 13 | this.api = api; 14 | this.pageSize = options.hasOwnProperty('pageSize') ? options.pageSize : 20; 15 | 16 | return this; 17 | }, 18 | 19 | /** 20 | * This paginates automatically over the document list from Prismic 21 | * @todo Add Lang support for scoping to a selection of languages. 22 | * 23 | * @param {String} type The Document type 24 | * @param {Number} next The Next Page type 25 | * @returns Promise 26 | */ 27 | async paginate(type, next = null) { 28 | const { results, total_pages, page } = await this.api.query( 29 | Prismic.Predicates.at("document.type", type), 30 | { 31 | lang: "*", 32 | pageSize: this.pageSize, 33 | page: next 34 | } 35 | ); 36 | 37 | if (results.length <= 0) { 38 | return Promise.resolve(); 39 | } 40 | 41 | this.results.push(...results); 42 | 43 | if (total_pages !== page) { 44 | return this.paginate(type, page + 1) 45 | } 46 | 47 | return Promise.resolve(); 48 | } 49 | } 50 | 51 | module.exports = paginator; 52 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [Unreleased] 8 | 9 | ## [0.5.3] - 2022-02-19 10 | 11 | * Publish again as version error 12 | 13 | ## [0.5.2] - 2022-02-19 14 | 15 | ### Changes 16 | * Update paginator.js by @ReeceM in https://github.com/ReeceM/prismic-sitemap/pull/22 17 | 18 | ## [0.5.1] - 2022-11-25 19 | 20 | ### Fixed 21 | - Fixed the workfile 22 | 23 | ## [0.5.0] - 2022-11-24 24 | 25 | ### Changes 26 | - The config usage option has changed, it must be done within the config area 27 | 28 | ### Fixed 29 | - Fixes issue [#18](https://github.com/ReeceM/prismic-sitemap/issues/18) 30 | 31 | ## [0.4.3] - 2022-07-28 32 | ### Fixed 33 | - Error where sometimes in NextJS duplicate entries were saved in the sitemap. 34 | 35 | ## [0.4.0] - 2021-07-24 36 | 37 | ### Feature 38 | - Added automatic pagination for all document types defined, or all that are returned. 39 | - this can also be configured with a pageSize per query if you wish to control that. 40 | 41 | ## [0.3.1] - 2021-07-24 42 | 43 | ### Fixed 44 | - Custom webpack function was not being called when running in isServer, @fattomhk, PR #11 45 | 46 | ## [0.3.0] - 2021-06-30 47 | 48 | ### Added 49 | - Option to make use of callback in `optionsMapPerDocumentType` see Discussion [Lastmod support #8](https://github.com/ReeceM/prismic-sitemap/discussions/8) 50 | - Added option to have a static path list of urls for normal routes that aren't dynamic 51 | 52 | ### Changed 53 | - Made the URL result from the linkResolver take priority on results that go into the sitemap 54 | - The `sitemapConfig` option is using the `lastmodDateOnly = true` setting to ensure all lastmod dates are `YYYY-MM-DD` only. But can be disabled to keep UTC time. 55 | 56 | ## [0.2.0] - 2021-06-14 57 | 58 | ### Changed 59 | - Made the default `documentTypes` = `['*']` to allow all documents to fetched if none are defined. 60 | 61 | ### Fixed 62 | - Missing access token for the API for Prismic, see #6 63 | 64 | ## [0.1.1] - 2021-03-22 65 | 66 | ### Fixed 67 | - fix dependencies in the package.json file, see #3 (@a-trost) and PR #4 68 | 69 | ## [0.1.0] - 2021-03-01 70 | 71 | First kind of functional version of the package and it also has the ability to have 72 | ### Added 73 | - Integration tests and improved unit test 74 | 75 | ### Fixed 76 | - The `path` package was missing inside the `index.js` next config file 77 | 78 | ## [0.0.2] - 2021-03-01 79 | 80 | ### Added 81 | - Allow the filename to be changed 82 | 83 | ### Fixed 84 | - The public path was not resolved properly 85 | - Defaults to using the next dir when from the `next.config.js` file 86 | - Will us the a local public folder when running directly when not defined 87 | 88 | 89 | ## [0.0.1] - 2021-02-28 90 | ### Added 91 | - Initial File 92 | - Docs and such 93 | 94 | [Unreleased]: https://github.com/reecem/prismic-sitemap/compare/v0.5.3...HEAD 95 | [0.5.3]: https://github.com/ReeceM/prismic-sitemap/compare/v0.5.2...v0.5.3 96 | [0.5.2]: https://github.com/ReeceM/prismic-sitemap/compare/v0.5.1...v0.5.2 97 | [0.5.1]: https://github.com/reecem/prismic-sitemap/compare/v0.5.1...HEAD 98 | [0.5.0]: https://github.com/reecem/prismic-sitemap/compare/v0.5.0...v0.5.1 99 | [0.4.3]: https://github.com/reecem/prismic-sitemap/compare/v0.4.3...v0.5.0 100 | [0.4.2]: https://github.com/reecem/prismic-sitemap/compare/v0.4.2...v0.4.3 101 | [0.4.1]: https://github.com/reecem/prismic-sitemap/compare/v0.4.1...v0.4.2 102 | [0.4.0]: https://github.com/reecem/prismic-sitemap/compare/v0.4.0...v0.4.1 103 | [0.3.1]: https://github.com/reecem/prismic-sitemap/compare/v0.3.1...v0.4.0 104 | [0.3.0]: https://github.com/reecem/prismic-sitemap/compare/v0.3.0...v0.3.1 105 | [0.2.0]: https://github.com/reecem/prismic-sitemap/compare/v0.2.0 106 | [0.1.1]: https://github.com/reecem/prismic-sitemap/tag/v0.1.0 107 | [0.1.0]: https://github.com/reecem/prismic-sitemap/tag/v0.1.0 108 | [0.0.2]: https://github.com/reecem/prismic-sitemap/tag/v0.0.2 109 | [0.0.1]: https://github.com/reecem/prismic-sitemap/tag/v0.0.1 110 | -------------------------------------------------------------------------------- /generator.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const fs = require("fs"); 3 | const Prismic = require("prismic-javascript"); 4 | const { SitemapStream, streamToPromise } = require('sitemap'); 5 | const paginatorUtil = require('./utils/paginator') 6 | 7 | /** 8 | * Generates a sitemap 9 | * 10 | * @param {Object} sitemap The Sitemap Object 11 | * @param {Function} sitemap.linkResolver 12 | * @param {String} sitemap.apiEndpoint 13 | * @param {String} sitemap.accessToken 14 | * @param {String} sitemap.hostname 15 | * @param {Array} sitemap.optionsMapPerDocumentType 16 | * @param {Array} sitemap.documentTypes 17 | * @param {Object} sitemap.sitemapConfig 18 | * @param {Object} sitemap.defaultEntryOption 19 | * @param {Object[]} sitemap.staticPaths 20 | */ 21 | const generator = async (sitemap) => { 22 | 23 | const { 24 | linkResolver = null /* doc => { return something } */, 25 | apiEndpoint = '', 26 | accessToken = null, 27 | hostname = '', 28 | optionsMapPerDocumentType = {}, 29 | documentTypes = ['*'], 30 | pagination = { 31 | pageSize: 20, 32 | }, 33 | fileName = 'sitemap.xml', 34 | publicPath = 'public', 35 | sitemapConfig = { 36 | lastmodDateOnly: true, 37 | }, 38 | defaultEntryOption = { changefreq: "monthly", priority: 1, }, 39 | staticPaths = [], 40 | /** optional things */ 41 | // onBeforeWrite = docs => docs, 42 | // onBeforeStore = stream => stream, 43 | } = sitemap; 44 | 45 | if (typeof linkResolver !== 'function') { 46 | throw new Error( 47 | '[Sitemap Generator]: The linkResolver function is undefined, this is needed to build sitemap links' 48 | ); 49 | } 50 | 51 | if (accessToken !== null && accessToken.length <= 1) { 52 | throw new Error( 53 | '[Sitemap Generator]: The API Access token appears incorrect, please double check as it is short.' 54 | ); 55 | } 56 | 57 | if (documentTypes === null || documentTypes.length <= 0) { 58 | throw new Error( 59 | '[Sitemap Generator]: The documentTypes option needs a value of 1 or greater in the array' 60 | ); 61 | } 62 | 63 | /** @todo Add extended options to the Prismic API function, or to pass one from user level */ 64 | const api = await Prismic.getApi(apiEndpoint, { 'accessToken': accessToken, }); 65 | const paginator = paginatorUtil.init(api, pagination); 66 | 67 | let documents = []; 68 | let types = Array.isArray(documentTypes) ? documentTypes : Array.of(documentTypes) 69 | 70 | await Promise.all(types.flatMap(type => paginator.paginate(type))) 71 | 72 | documents = paginator.results; 73 | 74 | const sitemapStream = new SitemapStream({ hostname: hostname, ...sitemapConfig }); 75 | 76 | documents 77 | .sort((a, b) => a.type < b.type ? -1 : 1) // sort by type 78 | .forEach(doc => { 79 | 80 | const options = optionsMapPerDocumentType.hasOwnProperty(doc.type) 81 | ? resolveDocumentOption(optionsMapPerDocumentType[doc.type], doc) 82 | : defaultEntryOption; 83 | 84 | sitemapStream.write( 85 | Object.assign({ ...options }, { url: linkResolver(doc) }) 86 | ); 87 | }) 88 | 89 | /* Handle adding a list of static paths to the sitemap, must be an object */ 90 | try { 91 | staticPaths.length >= 1 92 | ? staticPaths.forEach(path => storeIfValid(path, sitemapStream)) 93 | : null; 94 | } catch (error) { 95 | console.error('[Sitemap Generator]: Unable to save staticPaths to sitemap') 96 | } 97 | 98 | sitemapStream.end(); 99 | 100 | const sitemapData = await streamToPromise(sitemapStream); 101 | 102 | let basePath = resolvePublicPath(publicPath) 103 | 104 | if (!fs.existsSync(path.join(basePath))) { 105 | fs.mkdirSync(path.join(basePath), { recursive: true }); 106 | } 107 | 108 | fs.writeFileSync(path.join(basePath, fileName), sitemapData, "utf-8"); 109 | 110 | return sitemapData; 111 | } 112 | 113 | function resolvePublicPath(dir) { 114 | if (dir === 'public') { 115 | dir = path.join(__dirname, dir); 116 | } 117 | 118 | return dir; 119 | } 120 | 121 | /** 122 | * Resolves if the option is a callback and handles it 123 | * or continues with the object entry. 124 | * @param {Object|Function} option 125 | * @param {Object} document 126 | * @returns Object 127 | */ 128 | function resolveDocumentOption(option, document) { 129 | try { 130 | return typeof option === 'function' 131 | ? option(document) 132 | : option; 133 | 134 | } catch (error) { 135 | // console.error('[Sitemap Generator]: Failed to handle callback for a document', error); 136 | 137 | throw new Error( 138 | `[Sitemap Generator]: Failed to generate a sitemap entry for document {${document.type}}, ${error.message}` 139 | ); 140 | } 141 | } 142 | 143 | /** 144 | * Adds the static path to the index 145 | * 146 | * @todo Make use of a async callback or handle the object depending on what happens 147 | * @param {Object} option the static path to add 148 | * @param {SitemapStream} stream 149 | * @returns void 150 | */ 151 | function storeIfValid(option, stream) { 152 | 153 | if (typeof option === 'function') { 154 | option = option() 155 | } 156 | 157 | if (option.url === undefined) { 158 | return; 159 | } 160 | 161 | option.lastmod = option.lastmod ? option.lastmod : (new Date).toISOString() 162 | 163 | stream.write(option); 164 | } 165 | 166 | module.exports = generator; 167 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Prismic Sitemap Generator 2 | [![Node.js CI](https://github.com/ReeceM/prismic-sitemap/actions/workflows/node.js.yml/badge.svg?branch=main)](https://github.com/ReeceM/prismic-sitemap/actions/workflows/node.js.yml) 3 | [![Package Deploy](https://github.com/ReeceM/prismic-sitemap/actions/workflows/npm-publish.yml/badge.svg)](https://github.com/ReeceM/prismic-sitemap/actions/workflows/npm-publish.yml) 4 | [![GitHub license](https://img.shields.io/github/license/ReeceM/prismic-sitemap?style=flat)](https://github.com/ReeceM/prismic-sitemap/blob/master/LICENSE) 5 | [![npm](https://img.shields.io/npm/v/@reecem/prismic-sitemap)](https://www.npmjs.com/package/@reecem/prismic-sitemap) 6 | [![npm](https://img.shields.io/npm/dt/@reecem/prismic-sitemap)](https://www.npmjs.com/package/@reecem/prismic-sitemap) 7 | 8 | An easy to configure sitemap generator for Next.js websites based on the pages in your [Prismic.io](https://prismic.io) CMS. 9 | 10 | ## About 11 | 12 | This package uses the [Sitemap.js](https://github.com/ekalinin/sitemap.js) package to generate the sitemaps as it handles all the needed stuff for sitemaps. This also gives the end user flexibility in generating the sitemap. 13 | 14 | It aims to simplify the configuration required to create the sitemap, and also include it in the build process of your Next.js site by extending the `next.config.js` file. 15 | 16 | > This package is also inspired by the live steam from Prismic.io where they built a sitemap generator. But wanting to make it better like. 17 | 18 | ## Installation 19 | 20 | You can use either `npm` or `yarn` to install the package: 21 | 22 | ### NPM 23 | ```bash 24 | npm install --save-dev @reecem/prismic-sitemap 25 | ``` 26 | 27 | ### Yarn 28 | ```bash 29 | yarn add -D @reecem/prismic-sitemap 30 | ``` 31 | 32 | ## Usage 33 | 34 | The package is configured and used inside the `next.config.js` file. 35 | 36 | It works in a similar way to most Next.js plugins, it will also call the top-level `webpack()` function in the `next.config.js` file. 37 | 38 | ### Basic usage 39 | A basic Next.js file that has the sitemap generator plugin running would like as follows: 40 | 41 | ```javascript 42 | 43 | // The Prismic API endpoint 44 | const API_ENDPOINT = `https://${process.env.REPOSITORY_NAME}.cdn.prismic.io/api/v2`; 45 | 46 | // The hostname of the website, for example it would be https://example.com 47 | const SITE_URL = process.env.VERCEL_ENV; 48 | 49 | // this is the link resolver for the documents that are fetched. 50 | const linkResolver = doc => { 51 | 52 | if (doc.type == 'post') { 53 | return `blog/${doc.uid}`; 54 | } 55 | 56 | return `${doc.uid}`; 57 | }; 58 | 59 | const withPrismicSitemap = require('@reecem/prismic-sitemap')({ 60 | linkResolver: linkResolver, 61 | apiEndpoint: API_ENDPOINT, 62 | hostname: SITE_URL, 63 | optionsMapPerDocumentType: { 64 | // setting the update date of the article. 65 | post: (document) => { 66 | return { 67 | // get the last time the document was published in Prismic 68 | lastmod: document.last_publication_date, 69 | changefreq: "weekly", 70 | priority: 0.8 71 | } 72 | } 73 | page: { changefreq: "monthly", priority: 1 } 74 | }, 75 | documentTypes: ['page', 'post'] 76 | }); 77 | 78 | module.exports = withPrismicSitemap({ 79 | ... other nextConfig things here... or before :) 80 | }) 81 | ``` 82 | 83 | ### Multiple Page usage / Multilang too 84 | A more complex example would be to have multiple page types and also multi-language support inside the sitemap. 85 | 86 | This one will use a linkResolver that picks if it should use the default local pattern or the localized version and sets that as a prefix. 87 | 88 | ```javascript 89 | // The Prismic API endpoint 90 | const API_ENDPOINT = `https://${process.env.REPOSITORY_NAME}.cdn.prismic.io/api/v2`; 91 | 92 | // The hostname of the website, for example it would be https://example.com 93 | const SITE_URL = process.env.VERCEL_ENV; 94 | 95 | const linkResolver = doc => { 96 | const prefix = doc.lang !== "en-za" ? `/${doc.lang}` : ""; 97 | 98 | switch (doc.type) { 99 | case "homepage": 100 | case "pricing": 101 | case "page": 102 | return `${prefix}/${doc.uid ? doc.uid : ''}`; 103 | 104 | case "post": 105 | return `${prefix}/blog/${doc.uid}`; 106 | 107 | case "legal": 108 | return `${prefix}/legal/${doc.uid}`; 109 | 110 | case "product": 111 | return `${prefix}/product/${doc.uid}`; 112 | 113 | default: 114 | throw new Error(`Unknown doc.type: "${doc.type}"`); 115 | } 116 | }; 117 | 118 | const withPrismicSitemap = require('@reecem/prismic-sitemap')({ 119 | linkResolver: linkResolver, 120 | apiEndpoint: API_ENDPOINT, 121 | hostname: SITE_URL, 122 | optionsMapPerDocumentType: { 123 | page: { changefreq: "monthly", priority: 1 }, 124 | // homepage: { changefreq: "monthly", priority: 1 }, Homepage would default to this as it isn't found 125 | // legal: { changefreq: "monthly", priority: 1 }, Legal types would default to this as it isn't found 126 | post: { changefreq: "weekly", priority: 0.8 }, 127 | pricing: { changefreq: "monthly", priority: 1 } 128 | }, 129 | documentTypes: ['homepage', 'page', 'pricing', 'legal'] 130 | }) 131 | 132 | module.exports = withPrismicSitemap({ 133 | ... other nextConfig things here... or before :) 134 | }) 135 | ``` 136 | 137 | ### Private Prismic Repo Usage 138 | 139 | If you are using a closed or private prismic repository, you may need to use the API token to get published documents. From version 0.2.0 you can add the token. 140 | 141 | Below is an example, you need to add the `sitemap.accessToken` to the config. 142 | 143 | ```javascript 144 | 145 | // The Prismic API endpoint 146 | const API_ENDPOINT = `https://${process.env.REPOSITORY_NAME}.cdn.prismic.io/api/v2`; 147 | 148 | // The hostname of the website, for example it would be https://example.com 149 | const SITE_URL = process.env.VERCEL_ENV; 150 | 151 | // this is the link resolver for the documents that are fetched. 152 | const linkResolver = doc => { 153 | 154 | if (doc.type == 'post') { 155 | return `blog/${doc.uid}`; 156 | } 157 | 158 | return `${doc.uid}`; 159 | }; 160 | 161 | const withPrismicSitemap = require('@reecem/prismic-sitemap')(sitemap: { 162 | linkResolver: linkResolver, 163 | apiEndpoint: API_ENDPOINT, 164 | accessToken: process.env.PRISMIC_ACCESS_TOKEN, 165 | hostname: SITE_URL, 166 | optionsMapPerDocumentType: { 167 | post: { changefreq: "weekly", priority: 0.8 }, 168 | page: { changefreq: "monthly", priority: 1 } 169 | }, 170 | documentTypes: ['page', 'post'] 171 | }) 172 | 173 | module.exports = withPrismicSitemap({ 174 | ... other nextConfig things here.. 175 | }) 176 | ``` 177 | 178 | ### `` support 179 | 180 | The package makes use of lastmod support for the sitemap, this would need to be set by the user if you would want the date to come through at the current version of `0.3.0`. 181 | 182 | Because the Sitemap file is written using a separate package, it supports parsing the date straight to the `YYYY-MM-DD` format, if you would like it to have the time as well, you will need to override the setting in the config: 183 | 184 | ```javascript 185 | sitemap: { 186 | 187 | sitemapConfig: { 188 | lastmodDateOnly: false, 189 | }, 190 | 191 | } 192 | ``` 193 | 194 | ## API 195 | 196 | The sitemap object is made up of the following: 197 | 198 | ```javascript 199 | 200 | { 201 | sitemap: { 202 | linkResolver = Function, 203 | apiEndpoint = String, 204 | accessToken = String|null, 205 | hostname = String, 206 | fileName = String, 207 | optionsMapPerDocumentType = Object|Object, 208 | defaultEntryOption = Object, 209 | staticPaths = Array, 210 | pagination = { 211 | pageSize: Number, 212 | }, 213 | documentTypes = Array, 214 | sitemapConfig = Object 215 | } 216 | } 217 | ``` 218 | 219 | |Option|Type|eg|Description| 220 | |------|----|--|-----------| 221 | |linkResolver|function|```doc => {return `/path/${doc.uid}`;}```| This is the Prismic.io link resolver, this could be custom, or used from the prismic-configuration files.| 222 | |apiEndpoint|string|`'https://some-repository-on-prismic.cdn.prismic.io/api/v2'`| This is the URL of your Prismic repository, the API version of it.| 223 | |accessToken|string(optional)|`'random_api_string_that_you_get'`| This is the Access token used to access private Prismic Repositories| 224 | |hostname|string|`'http://example.com/'`| The hostname of your Vercel/Next.js application| 225 | |fileName|string|`'sitemap.xml'`| The name of the sitemap, it is always placed inside public| 226 | |optionsMapPerDocumentType|object|`{ page: { changefreq: "monthly", priority: 1 }, post: (doc) => {lastmod: doc.last_publication_date}}`| The options for the documents that are indexed, this can also have other options, found at [https://github.com/ekalinin/sitemap.js/blob/master/api.md#sitemap-item-options](https://github.com/ekalinin/sitemap.js/blob/master/api.md#sitemap-item-options)| 227 | |documentTypes|array|`['homepage', 'page', 'pricing', 'legal']`|| 228 | |defaultEntryOption|object (optional)| `{ changefreq: "monthly", priority: 1, }`| This is the default to add when nothing exists for the type or callback for entries| 229 | |staticPaths|array|`[{ url: '/static/path', changefreq: "yearly", priority: 1, lastmod: '2000-01-01'}]`| Use this if you would like to define a custom path for the Sitemap that doesn't come from the CMS | 230 | |pagination.pageSize|number|`{pagination: {pageSize: 30}}`|This sets the number of pages per request on the automatic pagination. Defaults to 20 per request| 231 | |sitemapConfig|object|| see [https://github.com/ekalinin/sitemap.js#options-you-can-pass](https://github.com/ekalinin/sitemap.js#options-you-can-pass)| 232 | 233 | 234 | ### `optionsMapPerDocumentType` 235 | 236 | The `optionsMapPerDocumentType` setting for the sitemap value allows you to configure the object result for the sitemap entry for the specific document 237 | 238 | This accepts a object with keys to the document type from Prismic, the value can be a object, or a callback. 239 | 240 | **Using the Callback** 241 | 242 | This option allows you to determine extra data about the document and return a object to be written to the Sitemap, there isn't a need to return the URL value, and this will be purged from the result anyway in favour of the `linkResolver` result. This is for consistency reasons. 243 | 244 | The primary reason to add this is because of using the `` XML attribute in the Sitemap to improve indexing by Google or other search engines. 245 | 246 | To make use of this, you can do the following logic: 247 | 248 | ```javascript 249 | const withPrismicSitemap = require('@reecem/prismic-sitemap')({ 250 | sitemap: { 251 | // ... other cofing 252 | optionsMapPerDocumentType: { 253 | post: (document) => { 254 | return { 255 | lastmod: document.last_publication_date ? document.last_publication_date : (new Date()).toJSON(), 256 | changefreq: 'monthly' 257 | }; 258 | } 259 | }, 260 | } 261 | }) 262 | ``` 263 | 264 | --- 265 | 266 | ## Testing 267 | 268 | ```bash 269 | npm run test 270 | ``` 271 | 272 | ```bash 273 | yarn test 274 | ``` 275 | 276 | ## Changelog 277 | 278 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 279 | 280 | ## Contributing 281 | 282 | Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details. 283 | 284 | ## Security Vulnerabilities 285 | 286 | Please review [our security policy](../../security/policy) on how to report security vulnerabilities. 287 | 288 | ## Credits 289 | 290 | - [ReeceM](https://github.com/ReeceM) 291 | - [All Contributors](../../contributors) 292 | 293 | ## License 294 | 295 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 296 | --------------------------------------------------------------------------------