{"id":15284367,"url":"https://github.com/static-dev/spike-contentful","last_synced_at":"2025-04-12T23:21:59.741Z","repository":{"id":10033128,"uuid":"64154403","full_name":"static-dev/spike-contentful","owner":"static-dev","description":":paperclip: Plugin to consume content from the CMS Contentful's API","archived":false,"fork":false,"pushed_at":"2022-02-12T12:47:43.000Z","size":591,"stargazers_count":19,"open_issues_count":25,"forks_count":15,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-06T13:43:34.633Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/static-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-07-25T17:29:23.000Z","updated_at":"2019-03-04T17:48:26.000Z","dependencies_parsed_at":"2022-08-07T05:15:24.467Z","dependency_job_id":null,"html_url":"https://github.com/static-dev/spike-contentful","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/static-dev%2Fspike-contentful","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/static-dev%2Fspike-contentful/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/static-dev%2Fspike-contentful/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/static-dev%2Fspike-contentful/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/static-dev","download_url":"https://codeload.github.com/static-dev/spike-contentful/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248625495,"owners_count":21135513,"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":[],"created_at":"2024-09-30T14:54:12.901Z","updated_at":"2025-04-12T23:21:59.705Z","avatar_url":"https://github.com/static-dev.png","language":"JavaScript","readme":"# Spike Contentful Plugin\n\n[![npm](http://img.shields.io/npm/v/spike-contentful.svg?style=flat-square)](https://badge.fury.io/js/spike-contentful) [![tests](http://img.shields.io/travis/static-dev/spike-contentful/master.svg?style=flat-square)](https://travis-ci.org/static-dev/spike-contentful) [![dependencies](http://img.shields.io/david/static-dev/spike-contentful.svg?style=flat-square)](https://david-dm.org/static-dev/spike-contentful)\n[![coverage](http://img.shields.io/coveralls/static-dev/spike-contentful.svg?style=flat-square)](https://coveralls.io/github/static-dev/spike-contentful)\n\n[Contentful CMS](https://www.contentful.com/) plugin for [spike](https://github.com/static-dev/spike)\n\n\u003e **Note:** This project is in early development, and versioning is a little different. [Read this](http://markup.im/#q4_cRZ1Q) for more details.\n\n### Why should you care?\n\nIf you're using [Contentful](https://www.contentful.com/) and would like to pull your data for compilation into a [spike](https://github.com/static-dev/spike) static site, this will help you out.\n\n### Installation\n\n`npm install spike-contentful -S`\n\n### Usage\n\nThis is a standard [webpack](https://webpack.github.io/) plugin, but is built for and intended to be used with [spike](https://github.com/static-dev/spike). You can include it in your spike project as such:\n\n```js\n// app.js\nconst Contentful = require('spike-contentful')\nconst htmlStandards = require('reshape-standard')\nconst locals = {}\n\nmodule.exports = {\n  plugins: [\n    new Contentful({\n      addDataTo: locals,\n      accessToken: 'xxx',\n      spaceId: 'xxx',\n      contentTypes: [\n        {\n          name: 'posts',\n          id: '633fTeiMaxxxxxxxxx'\n        },\n        {\n          name: 'authors',\n          id: '223gTahLaxxxxxxxxx'\n        }\n      ]\n    })\n  ],\n  reshape: htmlStandards({ locals: () =\u003e locals })\n}\n```\n\nAt a minimum, the `spike-contentful` plugin requires both `name` and `id` for `contentTypes`. The `name` corresponds with how you'd like to access it in your templates. The `id` is found listed under \"Identifier\" by logging into Contentful and clicking \"APIs\" then \"Content model explorer\".\n\nSince Spike uses `reshape`, you can use a variety of different plugins to expose local variables to your html. We are using [reshape](https://github.com/reshape/reshape) along with [spike html standards](https://github.com/static-dev/spike-html-standards) here because it's the plugin provided in spike's default template, and also is currently the only plugin that provides the ability to run complex loops through objects.\n\nIn order to pass the data correctly, you must pass `spike-contentful` an object, which it will load the data onto when the compile begins under a `contentful` key. If you also pass the same object to whatever `reshape` plugin you are using in whatever manner it requires to make the data available in your html templates, the data will be present on that object before they start compiling. This is a slightly unconventional pattern for Javascript libraries, but in this situation it allows for maximum flexibility and convenience.\n\nOnce included, it will expose a `contentful` local to your markup (`.sgr`, `.html`, etc...) files, which you can use to iterate through your content types. Based on the example above, the `posts` content type will be accessible through `contentful.posts`, as such:\n\n```jade\n// a template file\nul\n  each(loop='post of contentful.posts')\n    li {{ JSON.stringify(post) }}\n```\n\nFor the sugar-free\n\n```html\n\u003cul\u003e\n\t\u003ceach loop=\"post of contentful.blog\"\u003e\n\t\t\u003cli\u003e{{ JSON.stringify(post) }}\u003c/li\u003e\n\t\u003c/each\u003e\n\u003c/ul\u003e\n```\n\n### Filters\n\n#### Limit\n\nTo limit the number of results for a given content type:\n\n```js\nnew Contentful({\n  addDataTo: locals,\n  accessToken: 'xxx',\n  spaceId: 'xxx',\n  contentTypes: [\n    {\n      name: 'posts',\n      id: '633fTeiMaxxxxxxxxx',\n      filters: {\n        limit: 10\n      }\n    }\n  ]\n})\n```\n\n#### Order\n\nTo order results of a given content type:\n\n```js\nnew Contentful({\n  addDataTo: locals,\n  accessToken: 'xxx',\n  spaceId: 'xxx',\n  contentTypes: [\n    {\n      name: 'posts',\n      id: '633fTeiMaxxxxxxxxx',\n      filters: {\n        limit: 10,\n        order: 'sys.createdAt'\n      }\n    }\n  ]\n})\n```\n\n### Returning Linked Content Entries\n\nContentful allows you to link content types with a field called references. This can create a chain of links. For example __Content Entry A__ could contain a reference to __Content Entry B__, and __Content Entry B__ could further reference __Content Entry C__. \n\nContentful's default settings return only the first level of links, meaning that returning __Content Entry A__ from above will also retun __Content Entry B__, but not __Content Entry C__. Spike has an option called includeLevel that can be included in your Contentful object, which will allow you to return more levels of links than the default 1. This is extremely helpful if your content model relies heavily on references.\n\n```js\nnew Contentful({\n  addDataTo: locals,\n  accessToken: 'xxx',\n  spaceId: 'xxx',\n  includeLevel: 10,\n  contentTypes: [\n    {\n      name: 'posts',\n      id: '633fTeiMaxxxxxxxxx',\n      filters: {\n        limit: 10,\n        order: 'sys.createdAt'\n      }\n    }\n  ]\n})\n```\n\n### Transforms\n\nContentful returns a lot of associated data and, as a result, we give you the ability to pass your own custom `transform` option to each content type allowing you to transform the data however you like before it's sent to your views.\n\n```js\nnew Contentful({\n  addDataTo: locals,\n  accessToken: 'xxx',\n  spaceId: 'xxx',\n  contentTypes: [\n    {\n      name: 'posts',\n      id: '633fTeiMaxxxxxxxxx',\n      transform: post =\u003e {\n        // do your transformation here...\n        return post\n      }\n    }\n  ]\n})\n```\n\n### Templates\n\nUsing the template option allows you to write objects returned from Contentful to single page templates. For example, if you are trying to render a blog as static, you might want each post returned from the API to be rendered as a single page by itself.\n\nThe `template` option is an object with `path` and `output` keys. The `path` is an absolute or relative path to a template to be used to render each item, and output is a function with the currently iterated item as a parameter, which should return a string representing a path relative to the project root where the single view should be rendered. For example:\n\n```js\nnew Contentful({\n  addDataTo: locals,\n  accessToken: 'xxx',\n  spaceId: 'xxx',\n  contentTypes: [\n    {\n      name: 'posts',\n      id: '633fTeiMaxxxxxxxxx',\n      template: {\n        path: 'templates/post.html',\n        output: post =\u003e {\n          return `posts/${post.id}.html`\n        }\n      }\n    }\n  ]\n})\n```\n\nYour template must use the `item` variable as seen below. Also note that this feature will not work if your template is ignored by spike.\n\n```html\n\u003cp\u003e{{item.title}}\u003c/p\u003e\n```\n\n### Preview Environment\n\nUsing [Spike Environments](https://spike.readme.io/docs/environments), you can change your default `app.js` to use [Contentful's preview API](https://www.contentful.com/developers/docs/references/content-preview-api/) by using your project's preview key (in this example, `yyy`).\n\n```js\nnew Contentful({\n  addDataTo: locals,\n  accessToken: 'yyy',\n  preview: true;\n  spaceId: 'xxx'\n})\n```\n\nThen set your `app.production.js` to:\n\n```js\nnew Contentful({\n  addDataTo: locals,\n  accessToken: 'xxx',\n  preview: false;\n  spaceId: 'xxx'\n})\n```\nFrom there, running `spike compile` will use the preview API, and `spike compile -e production` will use the regular content delivery API.\n\nThis can also be accomplished with a single `app.js` with the help of [Dotenv](https://www.npmjs.com/package/dotenv).\n\nRequire Dotenv in your `app.js` file, then modify the Contentful call to use your preview key (in this example, `yyy`).\n\n```js\nconst env = process.env.SPIKE_ENV;\n\nnew Contentful({\n  addDataTo: locals,\n  accessToken: env !== 'production' ? 'yyy' : 'xxx' ,\n  preview: env !== 'production';\n  spaceId: 'xxx'\n})\n```\n\n### JSON Output\n\nFinally, if you'd like to have the output written locally to a JSON file so that it's cached locally, you can pass the name of the file, resolved relative to your project's output, as a `json` option to the plugin. For example:\n\n```js\nnew Contentful({\n  addDataTo: locals,\n  accessToken: 'xxx',\n  spaceId: 'xxx',\n  contentTypes: [\n    {\n      name: 'posts',\n      id: '633fTeiMaxxxxxxxxx'\n    }\n  ],\n  json: 'data.json'\n})\n```\n\nYou may also choose to have the ouput written specifically for any content type :\n\n```js\nnew Contentful({\n  addDataTo: locals,\n  accessToken: 'xxx',\n  spaceId: 'xxx',\n  contentTypes: [\n    {\n      name: 'posts',\n      id: '633fTeiMaxxxxxxxxx',\n      // JSON output expected for this content type\n      json: 'posts.json'\n    },\n    {\n      name: 'press',\n      id: '4Em9bQeIQxxxxxxxxx'\n      // No JSON output needed for this content type\n    }\n  ],\n  // Save all content types data in one file\n  json: 'alldata.json'\n})\n```\n\n### Aggressive Refresh\n\nBy default, this plugin will only fetch data once when you start your watcher, for development speed purposes. This means that if you change your data, you will have to restart the watcher to pick up the changes. If you are in a phase where you are making frequent data changes and would like a more aggressive updating strategy, you can set the `aggressiveRefresh` option to `true`, and your dreams will come true. However, note that this will slow down your local development, as it will fetch and link all entires every time you save a file, so it's only recommended for temporary use.\n\n### Testing\n\nTo run the tests locally, you'll need to add a `test/.env` with your name and token values:\n\n* `cp test/.env.sample test/.env`\n* `accessToken` is derived from \"APIs\" \u003e \"Content Delivery API Keys\" in the Contentful admin section.\n* `spaceId` is also derived from \"APIs\" \u003e \"Content Delivery API Keys\" in the Contentful admin section.\n\n### License \u0026 Contributing\n\n* Details on the license [can be found here](LICENSE.md)\n* Details on running tests and contributing [can be found here](CONTRIBUTING.md)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstatic-dev%2Fspike-contentful","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstatic-dev%2Fspike-contentful","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstatic-dev%2Fspike-contentful/lists"}