{"id":15245081,"url":"https://github.com/ryanhefner/contentful-sitemap","last_synced_at":"2025-04-10T16:52:30.712Z","repository":{"id":40336560,"uuid":"178479890","full_name":"ryanhefner/contentful-sitemap","owner":"ryanhefner","description":"🗺 Build a dynamic sitemap.xml file based on content pulled in from Contentful via the Contentful API.","archived":false,"fork":false,"pushed_at":"2024-11-11T06:22:34.000Z","size":2335,"stargazers_count":12,"open_issues_count":35,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-01T17:58:16.975Z","etag":null,"topics":["contentful","contentful-js-sdk","sitemap","sitemap-generator","sitemap-xml"],"latest_commit_sha":null,"homepage":"https://www.pkgstats.com/pkg:contentful-sitemap","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ryanhefner.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"ryanhefner","patreon":"ryanhefner","open_collective":"ryanhefner","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2019-03-29T21:52:21.000Z","updated_at":"2024-01-19T11:20:16.000Z","dependencies_parsed_at":"2023-11-15T02:42:25.564Z","dependency_job_id":"e16f1aa2-bc16-4277-88d8-00a07f71643e","html_url":"https://github.com/ryanhefner/contentful-sitemap","commit_stats":{"total_commits":141,"total_committers":4,"mean_commits":35.25,"dds":"0.35460992907801414","last_synced_commit":"98aff1a664ad8ea69942d9220992480e0d3d5739"},"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanhefner%2Fcontentful-sitemap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanhefner%2Fcontentful-sitemap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanhefner%2Fcontentful-sitemap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ryanhefner%2Fcontentful-sitemap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ryanhefner","download_url":"https://codeload.github.com/ryanhefner/contentful-sitemap/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248256302,"owners_count":21073502,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["contentful","contentful-js-sdk","sitemap","sitemap-generator","sitemap-xml"],"created_at":"2024-09-29T13:06:24.447Z","updated_at":"2025-04-10T16:52:30.689Z","avatar_url":"https://github.com/ryanhefner.png","language":"JavaScript","funding_links":["https://github.com/sponsors/ryanhefner","https://patreon.com/ryanhefner","https://opencollective.com/ryanhefner"],"categories":[],"sub_categories":[],"readme":"# 🗺 contentful-sitemap\n\n[![npm](https://img.shields.io/npm/v/contentful-sitemap?style=flat-square)](https://www.pkgstats.com/pkg:contentful-sitemap)\n[![NPM](https://img.shields.io/npm/l/contentful-sitemap?style=flat-square)](LICENSE)\n[![npm](https://img.shields.io/npm/dt/contentful-sitemap?style=flat-square)](https://www.pkgstats.com/pkg:contentful-sitemap)\n[![Coveralls github](https://img.shields.io/coveralls/github/ryanhefner/contentful-sitemap?style=flat-square)](https://coveralls.io/github/ryanhefner/contentful-sitemap)\n[![CircleCI](https://img.shields.io/circleci/build/github/ryanhefner/contentful-sitemap?style=flat-square)](https://circleci.com/gh/ryanhefner/contentful-sitemap)\n![Snyk Vulnerabilities for GitHub Repo](https://img.shields.io/snyk/vulnerabilities/github/ryanhefner/contentful-sitemap?style=flat-square)\n\nDynamically generate an array of valid `sitemap` routes to enable building a live sitemap based on Contentful content via the Contentful API.\n\n## Install\n\nVia [npm](https://npmjs.com/package/contentful-sitemap)\n\n```sh\nnpm install contentful-sitemap\n```\n\nVia [Yarn](http://yarn.fyi/contentful-sitemap)\n\n```sh\nyarn add contentful-sitemap\n```\n\n\n## How to use\n\n`contentful-sitemap` requires a Contentful client in order to fetch entries from\nyour Contenful space in order to build your dynamic sitemap entries. So, make sure\nyou have `contentful` as a dependency in your project.\n\n__Install `contentful`__\n\n```sh\nnpm i -S contentful\n```\n\n__Create Contentful client__\n\n```js\nconst contentful = require('contentful');\nconst { ContentfulSitemap } = require('contentful-sitemap');\n\nconst client = contentful.createClient({\n  accessToken: '[ACCESS_TOKEN]',\n  space: '[SPACE_ID]',\n});\n```\n\nNext comes setting up the `ContentfulSitemap` instance that will be used by your\n`/sitemap.xml` route to generate and return the sitemap. `ContentfulSitemap` requires\na `client` instance, so make sure you pass one into the constructor.\n\n__Create `ContentfulSitemap` instance__\n\n```js\nconst sitemapGenerator = new ContentfulSitemap(client, [routes], {options});\n```\n\n### Parameters\n\n* `client` - Contentful client that will be used for fetching locales and entries from Contentful.\n\n* `routes` - Array of route definitions to use to generate sitemap.\n\n* `options` - Options that you can use to customize how sitemaps are generated.\n\n\n### Routes\n\n`contentful-sitemap` generates a route array that is compatible with the\n[`sitemap`](https://npmjs.com/package/sitemap) package for generating your\n`sitemap.xml` file, so all `route` options supported by that package are\nalso supported within the `routes` array you pass in. You can pass in both\nstatic and dynamic Contentful routes within the array. Below are the few\nspecifics that directly relate to how `contentful-sitemap` will process\nyour `routes` entries.\n\n| Name              | Default             | Description                                                                                                                                                                 |\n| ----------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `url`             | `null`              | Use this property if the path you are providing does not require any segments to be swapped out dynamically.                                                                |\n| `id`              | `null`              | Contentful entry `id` to fetch for the specific path. Only used if the `dynamicLastmod` option is set to  `true`.                                                           |\n| `pattern`         | `null`              | [`path-to-regexp`](https://npmjs.com/package/path-to-regexp) pattern to use for generating dynamic listings based on Contentful content or setting `locale` specific paths. |\n| `priority`        | `1`                 | Default `priority` to set for each `url`. Set to `1` as a default so it can be excluded in your `routes` definitions.                                                       |\n| `params`          | `null`              | Object used to specify the mapping of `pattern` parameter to Contentful response data.                                                                                      |\n| `query`           | `null`              | Query used by the Contentful `client` for fetching entries. All [contentful](https://npmjs.com/package/contentful) `getEntries` query options are supported.                |\n\n\n### Default Options\n\nThe following options can be used to customize the way your sitemap is generated.\nThe one option that you’ll definitely want to set, if not defined in your `routes`\nis the `origin` option, which is prefixed before the `url`s and `pattern`s defined\nin your routes.\n\n| Name              | Default             | Description                                                                           |\n| ----------------- | ------------------- | ------------------------------------------------------------------------------------- |\n| `locales`         | `[]`                | Array of locales to include for all route instances, if not using `dynamicLocales`.   |\n| `dynamicLocales`  | `false`             | Whether or not to fetch the list of enabled `locales` from Contentful.                |\n| `dynamicLastmod`  | `false`             | Automatically use the `lastmodParam` value of each entry to set the `lastmod` value.  |\n| `lastmodParam`    | `sys.updatedAt`     | Contentful model field to use when populating `lastmodISO` in route(s).               |\n| `localeParam`     | `locale`            | The param to set within your `pattern` to replace with a `locale`.                    |\n| `defaultLocale`   | `null`              | The default locale that will be used in the main `loc` value for a `url`.             |\n\n\n### Methods\n\n* `addRoute(route)` - Method to use for adding additional urls after the initial `ContentfulSitemap` instance has been created.\n\n* `buildRoutes()` - The magic✨ Call this method when you want to generate your Contentful routes to be passed to `sitemap`.\n\n* `toXML((xml, err) =\u003e {})` - __*DEPRECATED*__ - This was the previous method that this class used to build and return the full `sitemap.xml` string, but due to changes made to the `sitemap` package it seemed like it would be easier to support the current—and future—versions of that package by simplifying this package to do one thing well, while offering more flexibility with how you would like to use `sitemap` to generate your sitemap(s).\n\n## Example\n\n```js\nconst express = require('express');\nconst contentful = require('contentful');\nconst { SitemapStream, streamToPromise } = require('sitemap');\nconst { createGzip } = require('zlib');\nconst { ContentfulSitemap } = require('contentful-sitemap');\n\nconst app = express();\n\nconst client = contentful.createClient({\n  accessToken: '[ACCESS_TOKEN]',\n  space: '[SPACE_ID]',\n});\n\nconst sitemapGenerator = new ContentfulSitemap(client, [\n  {\n    pattern: '/',\n    id: '[HOME_PAGE_ID]',\n  },\n  {\n    pattern: '/about',\n    id: '[ABOUT_PAGE_ID]',\n    priority: 0.7,\n  },\n  {\n    pattern: '/news',\n    id: '[NEWS_PAGE_ID]',\n  },\n  {\n    pattern: '/news/:slug',\n    priority: 0.5,\n    query: {\n      content_type: '[CONTENTFUL_MODEL_TYPE (e.g. `newsArticlePage`)]',\n      select: 'fields.slug',\n    },\n    params: {\n      slug: 'fields.slug',\n    },\n  },\n  {\n    url: '/terms',\n    priority: 0.3,\n  },\n  {\n    url: '/privacy',\n    priority: 0.3,\n  }\n]);\n\nlet sitemap;\n\napp.get('/sitemap.xml', (req, res) =\u003e {\n  res.header('Content-Type', 'application/xml');\n  res.header('Content-Encoding', 'gzip');\n\n  if (sitemap) {\n    return res.send(sitemap);\n  }\n\n  try {\n    const smStream = new SitemapStream({ hostname: 'https://example.com/' });\n    const pipeline = smStream.pipe(createGzip());\n\n    return sitemapGenerator.buildRoutes()\n      .then(routes =\u003e {\n        // pipe your entries or directly write them.\n        routes.forEach(route =\u003e smStream.write(route));\n        smStream.end()\n\n        // cache the response\n        streamToPromise(pipeline).then(sm =\u003e sitemap = sm)\n        // stream write the response\n        pipeline.pipe(res).on('error', (e) =\u003e {throw e})\n      })\n      .catch(error =\u003e {\n        console.error(error);\n        res.status(500).end();\n      });\n  } catch (e) {\n    console.error(e)\n    res.status(500).end()\n  }\n});\n\n...\n\n```\n\n\n## License\n\n[MIT](LICENSE) © [Ryan Hefner](https://www.ryanhefner.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryanhefner%2Fcontentful-sitemap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fryanhefner%2Fcontentful-sitemap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fryanhefner%2Fcontentful-sitemap/lists"}