├── .gitignore ├── src ├── img │ ├── contentful.png │ └── cosmic.svg ├── style.css ├── cosmic.service.js ├── importer.service.js ├── index.js ├── contentful.service.js └── contentful-sample.json ├── public └── index.html ├── extension.json ├── README.md └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | .DS_Store 4 | extension.zip -------------------------------------------------------------------------------- /src/img/contentful.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cosmicjs/contentful-importer/master/src/img/contentful.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 |
-------------------------------------------------------------------------------- /extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Contentful Importer", 3 | "font_awesome_class": "fa-download", 4 | "image_url": "https://cdn.cosmicjs.com/2d015110-41f7-11ea-93cf-dfe709ea319d-cosmic-contentful.png", 5 | "repo_url": "https://github.com/cosmicjs/contentful-importer" 6 | } 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Contentful to Cosmic Importer 4 | 5 | Import your Contentful space into Cosmic JS. Read about [how it was built here](https://www.cosmicjs.com/articles/creating-the-cosmic-js-contentful-importer-k5qwyunz). 6 | 7 | ## Installation 8 | 9 | Go to Your Bucket > Settings > Extensions to find and install this Extension. Also available [here](https://www.cosmicjs.com/extensions/contentful-importer). 10 | 11 | To run locally: 12 | 13 | ``` 14 | npm install 15 | npm start 16 | ``` 17 | 18 | ## Building 19 | 20 | ``` 21 | npm run build 22 | ``` 23 | 24 | ## Deploy 25 | Runs a build and compress to zip. The zip will then need to be uploaded to the Extension area in your Bucket. 26 | 27 | ``` 28 | npm run deploy 29 | ``` 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react", 3 | "version": "0.0.0", 4 | "private": true, 5 | "dependencies": { 6 | "@contentful/rich-text-html-renderer": "^13.4.0", 7 | "cosmicjs": "^3.2.40", 8 | "pluralize": "^8.0.0", 9 | "prop-types": "^15.6.0", 10 | "react": "^16.9.0", 11 | "react-dom": "^16.9.0", 12 | "react-loading": "^2.0.3", 13 | "semantic-ui-react": "^0.88.2", 14 | "showdown": "^1.9.1" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "deploy": "npm run build && cp extension.json build/extension.json && zip -r build.zip build", 20 | "test": "react-scripts test --env=jsdom", 21 | "eject": "react-scripts eject" 22 | }, 23 | "devDependencies": { 24 | "fs-extra": "^8.1.0", 25 | "react-scripts": "latest", 26 | "zip-a-folder": "0.0.10" 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.2%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/style.css: -------------------------------------------------------------------------------- 1 | body, 2 | button, 3 | input { 4 | font-family: Lato; 5 | font-size: 15px; 6 | } 7 | 8 | button { 9 | padding: 5px 10px; 10 | } 11 | 12 | img { 13 | width: 300px; 14 | margin-right: 15px; 15 | } 16 | 17 | input { 18 | border: 1px solid grey; 19 | padding: 5px; 20 | } 21 | 22 | button, 23 | input { 24 | border-radius: 5px; 25 | } 26 | 27 | label { 28 | display: block; 29 | margin-bottom: 5px; 30 | } 31 | 32 | .root { 33 | background-color: #F5F7F9; 34 | height: 100%; 35 | padding: 20px 20px; 36 | } 37 | .objects-import-wrapper { 38 | position: absolute; 39 | width: 200px; 40 | height: 270px; 41 | top: -217px; 42 | overflow: hidden; 43 | left: -5px; 44 | } 45 | .objects-import { 46 | left: 0; 47 | transform: rotate(-90deg); 48 | z-index: 0; 49 | } 50 | .objects-import path { 51 | stroke-width: 7px; 52 | stroke-linecap: round; 53 | stroke-dasharray: 0 20; 54 | -webkit-animation: stroke-invert .8s linear infinite; 55 | animation: stroke-invert .8s linear infinite; 56 | } 57 | // Animation 58 | @keyframes stroke{to{stroke-dashoffset:20}}@-webkit-keyframes stroke-invert{to{stroke-dashoffset:-20}}@keyframes stroke-invert{to{stroke-dashoffset:-20}} 59 | .card-floating { 60 | box-shadow: rgba(0,21,64,.14) 0 2px 6px, rgba(0,21,64,.05) 0 10px 20px; 61 | border-radius: 200px; 62 | border: 14px solid #fff; 63 | background: #fff; 64 | z-index: 1; 65 | position: relative; 66 | padding: 20px; 67 | } -------------------------------------------------------------------------------- /src/cosmic.service.js: -------------------------------------------------------------------------------- 1 | import CosmicFactory from "cosmicjs"; 2 | 3 | export class CosmicService { 4 | bucket; 5 | 6 | constructor(slug, read_key, write_key) { 7 | const Cosmic = CosmicFactory(); 8 | 9 | this.bucket = Cosmic.bucket({ 10 | slug, 11 | read_key, 12 | write_key 13 | }); 14 | } 15 | 16 | addMediaObjects(media) { 17 | try { 18 | const promises = media.map(media => this.addMediaObject(media)); 19 | return Promise.all(promises); 20 | } catch (e) { 21 | console.log("caught at add media object", e); 22 | 23 | throw e; 24 | } 25 | } 26 | 27 | addMediaObject(params) { 28 | return new Promise((resolve, reject) => { 29 | this.bucket 30 | .addMedia(params) 31 | .then(data => { 32 | resolve(data); 33 | }) 34 | .catch(err => { 35 | resolve({ failed: true, e: err, file: params }); 36 | }); 37 | }); 38 | } 39 | 40 | addObjects(objectArr) { 41 | const promises = objectArr.map(object => this.addObject(object)); 42 | 43 | return Promise.all(promises); 44 | } 45 | 46 | addObject(params) { 47 | return new Promise((resolve, reject) => { 48 | this.bucket 49 | .addObject(params) 50 | .then(data => resolve(data)) 51 | .catch(err => { 52 | if (err.message && !err.message.includes("already exists")) { 53 | reject(err); 54 | } 55 | 56 | resolve(err); 57 | }); 58 | }); 59 | } 60 | 61 | addObjectTypes(typeArr) { 62 | const promises = typeArr.map(type => this.addObjectType(type)); 63 | 64 | return Promise.all(promises); 65 | } 66 | 67 | addObjectType(params) { 68 | return new Promise((resolve, reject) => { 69 | this.bucket 70 | .addObjectType(params) 71 | .then(data => resolve(data)) 72 | .catch(err => { 73 | if (err.message && !err.message.includes("already exists")) { 74 | reject(err); 75 | } 76 | 77 | resolve(err); 78 | }); 79 | }); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/img/cosmic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 12 | 14 | 16 | 18 | 20 | 22 | 23 | 24 | 26 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /src/importer.service.js: -------------------------------------------------------------------------------- 1 | export class ImporterService { 2 | contentful; 3 | cosmic; 4 | 5 | constructor(contentfulService, cosmicService) { 6 | this.contentful = contentfulService; 7 | this.cosmic = cosmicService; 8 | } 9 | 10 | loadContentfulContent(file, onProgress, onError, onComplete, onMessage) { 11 | const reader = new FileReader(); 12 | 13 | reader.readAsText(file, "UTF-8"); 14 | 15 | reader.onload = e => { 16 | try { 17 | const content = e.target.result; 18 | 19 | const json = JSON.parse(content); 20 | 21 | this._parseContent(json, onProgress, onError, onComplete, onMessage); 22 | } catch (e) { 23 | onError(e); 24 | } 25 | }; 26 | } 27 | 28 | async _parseContent(content, onProgress, onError, onComplete, onMessage) { 29 | try { 30 | this._validateContent(content); 31 | 32 | onProgress("Content valid. Parsing..."); 33 | 34 | const fields = this.contentful.toCosmicObjectTypes(content.contentTypes); 35 | 36 | onProgress("Successfully parsed content types"); 37 | 38 | await this.cosmic.addObjectTypes(fields.contentTypes); 39 | 40 | onProgress("Successfully created content types"); 41 | 42 | const media = ( 43 | await this.contentful.toCosmicMedia(content.assets, content.locales) 44 | ).filter(mediaObject => { 45 | if (!mediaObject) { 46 | return false; 47 | } else if (mediaObject.failed) { 48 | onMessage( 49 | `Failed to download image from contentful: ${mediaObject.title}` 50 | ); 51 | 52 | return false; 53 | } 54 | 55 | return true; 56 | }); 57 | 58 | onProgress("Successfully parsed media"); 59 | 60 | onProgress("Uploading media to Cosmic..."); 61 | 62 | const cosmicMedia = await this.cosmic.addMediaObjects(media); 63 | 64 | const successfulMedia = cosmicMedia.filter(media => { 65 | if (media.failed) { 66 | onMessage( 67 | `Failed to upload image: ${media.file.metadata.title} - ${media.file.metadata.originalUrl}` 68 | ); 69 | 70 | return false; 71 | } 72 | 73 | return true; 74 | }); 75 | 76 | onProgress("Successfully created media"); 77 | 78 | const parsedObjects = this.contentful.toCosmicObjects( 79 | content.entries, 80 | content.locales, 81 | fields.displayFieldMap, 82 | fields.metafieldDescriptors, 83 | successfulMedia 84 | ); 85 | 86 | onProgress("Successfully parsed entries"); 87 | 88 | await this.cosmic.addObjects(parsedObjects); 89 | 90 | onProgress("Successfully created objects"); 91 | 92 | onComplete(); 93 | } catch (e) { 94 | onError(e); 95 | console.log(e); 96 | } 97 | } 98 | 99 | _validateContent(content) { 100 | if ( 101 | !content || 102 | !content.contentTypes || 103 | !content.entries || 104 | !content.locales 105 | ) { 106 | throw new Error("invalid content"); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import { render } from "react-dom"; 3 | import { CosmicService } from "./cosmic.service"; 4 | import { ContentfulService } from "./contentful.service"; 5 | import { ImporterService } from "./importer.service"; 6 | import ReactLoading from "react-loading"; 7 | import "./style.css"; 8 | import { Input, Button, Modal, Header, Icon, Message } from 'semantic-ui-react' 9 | 10 | import cosmicLogo from "./img/cosmic.svg"; 11 | import contentfulLogo from "./img/contentful.png"; 12 | 13 | const getParam = param => { 14 | var urlParams = new URLSearchParams(window.location.search); 15 | return urlParams.get(param); 16 | }; 17 | 18 | class App extends Component { 19 | importerService; 20 | 21 | constructor() { 22 | super(); 23 | 24 | this.state = { 25 | file: null, 26 | slug: getParam("bucket_slug"), 27 | read_key: getParam("read_key"), 28 | write_key: getParam("write_key"), 29 | errorMessage: false, 30 | progress: false, 31 | loading: false, 32 | messages: [] 33 | }; 34 | 35 | this.createService(); 36 | 37 | this.closeSuccessModal = () => { 38 | this.setState({ 39 | ...this.state, 40 | progress: false 41 | }); 42 | } 43 | } 44 | 45 | 46 | render() { 47 | const { errorMessage, loading, progress, messages, slug } = this.state; 48 | if (progress === 'Successfully created objects') { 49 | return ( 50 | 51 |
52 | 53 |

54 | Your entries have been successfully imported!   Go see them   55 |

56 |
57 | 58 | 61 | 62 | 63 | ) 64 | } 65 | return ( 66 |
67 |

Contentful Importer

68 |
69 | Cosmic JS Logo 70 |
71 | 72 | 73 | 74 |
75 | Contentful Logo 76 |
77 |
78 |

79 | To import data from Contentful create an export file via the 80 | Contentful CLI then upload it here. 81 |

82 | Use the Contentful CLI to download a JSON file export of your space. Example: 83 | 84 | 85 | contentful space export --space-id YOUR_SPACE_ID --management-token YOUR_MANAGEMENT_TOKEN 86 | 87 | 88 |

89 | For more information follow the instructions here. 90 |

91 |
92 | {errorMessage ?
{errorMessage}
: ""} 93 | {loading ? : ""} 94 | {progress ?
{progress}
: ""} 95 | {messages.length ? ( 96 |
97 |

Messages:

98 |
    99 | {messages.map((message, i) => ( 100 |
  • {message}
  • 101 | ))} 102 |
103 |
104 | ) : ( 105 | "" 106 | )} 107 | {loading ? ( 108 | "" 109 | ) : ( 110 |
111 |
112 | this.setFile(e)} 116 | /> 117 |
118 | 119 |
120 | )} 121 |
122 | ); 123 | } 124 | 125 | completeCallback() { 126 | this.setState({ 127 | messages: this.state.messages, 128 | loading: false 129 | }); 130 | } 131 | 132 | createService() { 133 | const { slug, read_key, write_key } = this.state; 134 | 135 | if (!slug) { 136 | throw new Error("Set slug value"); 137 | } 138 | 139 | const cosmic = new CosmicService(slug, read_key, write_key); 140 | 141 | const contentful = new ContentfulService(); 142 | 143 | this.importerService = new ImporterService(contentful, cosmic); 144 | } 145 | 146 | errorCallback(message) { 147 | this.setState({ 148 | errorMessage: message.toString(), 149 | messages: this.state.messages, 150 | loading: false 151 | }); 152 | } 153 | 154 | parseFile() { 155 | try { 156 | this.setState({ 157 | messages: [], 158 | loading: true 159 | }); 160 | 161 | const { file } = this.state; 162 | 163 | if (!file) { 164 | throw new Error("No file provided"); 165 | } 166 | 167 | this.importerService.loadContentfulContent( 168 | file, 169 | m => this.progressCallback(m), 170 | e => this.errorCallback(e), 171 | () => this.completeCallback(), 172 | m => this.messageCallback(m) 173 | ); 174 | } catch (e) { 175 | this.errorCallback(e); 176 | } 177 | } 178 | 179 | messageCallback(m) { 180 | const { messages } = this.state; 181 | 182 | this.setState({ 183 | ...this.state, 184 | messages: [...messages, m] 185 | }); 186 | } 187 | 188 | progressCallback(message) { 189 | this.setState({ 190 | ...this.state, 191 | progress: message 192 | }); 193 | } 194 | 195 | setFile(e) { 196 | const file = e.target.files[0]; 197 | 198 | this.setState({ ...this.state, file }); 199 | } 200 | } 201 | 202 | render(, document.getElementById("root")); 203 | -------------------------------------------------------------------------------- /src/contentful.service.js: -------------------------------------------------------------------------------- 1 | import pluralize from "pluralize"; 2 | import showdown from "showdown"; 3 | import { documentToHtmlString } from "@contentful/rich-text-html-renderer"; 4 | 5 | function getMetafieldType(type, subtype) { 6 | if ( 7 | type === "Symbol" || 8 | type === "Boolean" || 9 | type === "Object" || 10 | type === "Location" 11 | ) { 12 | return "text"; 13 | } else if (type === "RichText") { 14 | return "html-textarea"; 15 | } else if (type === "Text") { 16 | return "markdown"; 17 | } else if (type === "Number" || type === "Integer" || type === "Decimal") { 18 | return "number"; 19 | } else if (type === "Date") { 20 | return "date"; 21 | } else if (type === "Asset") { 22 | return "file"; 23 | } else if (type === "Link" && subtype === "Asset") { 24 | return "file"; 25 | } else if (type === "Link") { 26 | return "object"; 27 | } else if (type === "Array") { 28 | return "objects"; 29 | } 30 | } 31 | 32 | function parseLink(link, media) { 33 | if (!link) { 34 | return; 35 | } else if (link.sys.type === "Link" && link.sys.linkType === "Entry") { 36 | return { 37 | type: "link", 38 | slug: link.sys.id 39 | }; 40 | } else if (link.sys.type === "Link" && link.sys.linkType === "Asset") { 41 | const mediaIndex = media.findIndex(mediaObject => { 42 | return ( 43 | !mediaObject.failed && 44 | mediaObject.media.metadata.contentfulId === link.sys.id 45 | ); 46 | }); 47 | 48 | const mediaObject = media[mediaIndex]; 49 | 50 | return ( 51 | mediaObject && { 52 | type: "media", 53 | name: mediaObject.media.name 54 | } 55 | ); 56 | } 57 | } 58 | 59 | export class ContentfulService { 60 | converter; 61 | 62 | constructor() { 63 | this.converter = new showdown.Converter(); 64 | } 65 | 66 | async toCosmicMedia(assets, locales) { 67 | const cosmicAssets = []; 68 | 69 | assets.forEach(asset => { 70 | locales.forEach(locale => 71 | cosmicAssets.push(this._createMediaObject(asset, locale)) 72 | ); 73 | }); 74 | 75 | return await Promise.all(cosmicAssets); 76 | } 77 | 78 | _createMediaObject(asset, locale) { 79 | return new Promise((resolve, reject) => { 80 | const { code } = locale; 81 | 82 | const localeFileObject = asset.fields.file[code]; 83 | 84 | if (!localeFileObject) { 85 | resolve(); 86 | } 87 | 88 | const url = localeFileObject.url; 89 | const req = fetch(url); 90 | 91 | const originalName = asset.fields.file[code].fileName; 92 | 93 | let contentType; 94 | 95 | req 96 | .then(res => { 97 | res.headers.forEach((val, key) => { 98 | if (key === "content-type") { 99 | contentType = val; 100 | } 101 | }); 102 | return res.blob(); 103 | }) 104 | .then(body => { 105 | const buffer = new File([body], originalName, { type: contentType }); 106 | 107 | const description = asset.fields.description 108 | ? asset.fields.description[code] 109 | : ""; 110 | 111 | resolve({ 112 | media: buffer, 113 | metadata: { 114 | description, 115 | contentfulId: asset.sys.id, 116 | locale: locale.code, 117 | title: asset.fields.title[code], 118 | originalUrl: url 119 | } 120 | }); 121 | }) 122 | .catch(e => { 123 | const error = { 124 | failed: true, 125 | title: originalName 126 | }; 127 | 128 | resolve(error); 129 | }); 130 | }); 131 | } 132 | 133 | toCosmicObjectTypes(contentTypes) { 134 | const objectTypes = { 135 | displayFieldMap: {}, 136 | metafieldDescriptors: {}, 137 | contentTypes: [] 138 | }; 139 | 140 | objectTypes.contentTypes = contentTypes.map(type => { 141 | const plural = pluralize.plural(type.name); 142 | const singular = pluralize.singular(type.name); 143 | 144 | objectTypes.displayFieldMap[type.sys.id] = type.displayField; 145 | 146 | objectTypes.metafieldDescriptors[type.sys.id] = { 147 | fields: {} 148 | }; 149 | 150 | const metafields = type.fields.map(field => { 151 | const metafield = { 152 | type: getMetafieldType(field.type, field.linkType), 153 | title: field.name, 154 | key: field.id, 155 | required: field.required, 156 | isSlug: field.name === "slug" || field.name === "Slug" 157 | }; 158 | 159 | objectTypes.metafieldDescriptors[type.sys.id].fields[ 160 | field.id 161 | ] = metafield; 162 | 163 | return metafield; 164 | }); 165 | 166 | return { 167 | title: plural, 168 | singular, 169 | slug: type.sys.id, 170 | metafields 171 | }; 172 | }); 173 | 174 | return objectTypes; 175 | } 176 | 177 | toCosmicObjects( 178 | entries, 179 | locales, 180 | displayFieldMap, 181 | metafieldDescriptors, 182 | media 183 | ) { 184 | const cosmicObjects = []; 185 | 186 | entries.forEach((entry, index) => { 187 | const object = { 188 | type_slug: entry.sys.contentType.sys.id, 189 | slug: entry.sys.id, 190 | status: "draft" 191 | }; 192 | 193 | locales.forEach((locale, index) => { 194 | const code = locale.code; 195 | let title = entry.fields[displayFieldMap[object.type_slug]][code]; 196 | 197 | if (!title) { 198 | if (entry.fields.title && entry.fields.title[code]) { 199 | title = entry.fields.title[code]; 200 | } else if (entry.fields.title) { 201 | const key = Object.keys(entry.fields.title)[0]; 202 | 203 | if (key) { 204 | title = entry.fields.title[key]; 205 | } else { 206 | title = "imported object"; 207 | } 208 | } else { 209 | title = "imported object"; 210 | } 211 | } 212 | 213 | const metafields = []; 214 | 215 | Object.keys(entry.fields).forEach(key => { 216 | const type = metafieldDescriptors[object.type_slug].fields[key]; 217 | const val = entry.fields[key][code]; 218 | 219 | if (type.isSlug) { 220 | object.slug = val; 221 | } 222 | 223 | const metafieldObject = { 224 | ...type 225 | }; 226 | 227 | if (type.type === "object" && val && val.sys) { 228 | metafieldObject.value = parseLink(val, media); 229 | } else if (type.type === "file") { 230 | const mediaVal = parseLink(val, media); 231 | if (!mediaVal) return; 232 | metafieldObject.value = mediaVal.name; 233 | } else if (type.type === "objects" && val && val[0] && val[0].sys) { 234 | metafieldObject.value = val.map(link => parseLink(link, media)); 235 | } else if (type.type === "html-textarea" && val) { 236 | if (typeof val === "object" && val.nodeType) { 237 | metafieldObject.value = documentToHtmlString(val); 238 | } else { 239 | metafieldObject.value = this.converter.makeHtml(val); 240 | } 241 | } else if (type.type === "text" && val && typeof val === "object") { 242 | metafieldObject.value = JSON.stringify(val); 243 | } else { 244 | metafieldObject.value = val; 245 | } 246 | 247 | metafields.push(metafieldObject); 248 | }); 249 | 250 | cosmicObjects.push({ 251 | ...object, 252 | title, 253 | metafields, 254 | locale: code 255 | }); 256 | }); 257 | }); 258 | 259 | return cosmicObjects; 260 | } 261 | } 262 | -------------------------------------------------------------------------------- /src/contentful-sample.json: -------------------------------------------------------------------------------- 1 | { 2 | "contentTypes": [ 3 | { 4 | "sys": { 5 | "space": { 6 | "sys": { 7 | "type": "Link", 8 | "linkType": "Space", 9 | "id": "6yhac0bg4wbt" 10 | } 11 | }, 12 | "id": "person", 13 | "type": "ContentType", 14 | "createdAt": "2020-01-12T20:11:27.526Z", 15 | "updatedAt": "2020-01-12T20:11:30.857Z", 16 | "environment": { 17 | "sys": { 18 | "id": "master", 19 | "type": "Link", 20 | "linkType": "Environment" 21 | } 22 | }, 23 | "publishedVersion": 1, 24 | "publishedAt": "2020-01-12T20:11:30.857Z", 25 | "firstPublishedAt": "2020-01-12T20:11:30.857Z", 26 | "createdBy": { 27 | "sys": { 28 | "type": "Link", 29 | "linkType": "User", 30 | "id": "1lkP8MOZgpIuq3eOIdgDou" 31 | } 32 | }, 33 | "updatedBy": { 34 | "sys": { 35 | "type": "Link", 36 | "linkType": "User", 37 | "id": "1lkP8MOZgpIuq3eOIdgDou" 38 | } 39 | }, 40 | "publishedCounter": 1, 41 | "version": 2, 42 | "publishedBy": { 43 | "sys": { 44 | "type": "Link", 45 | "linkType": "User", 46 | "id": "1lkP8MOZgpIuq3eOIdgDou" 47 | } 48 | } 49 | }, 50 | "displayField": "name", 51 | "name": "Person", 52 | "description": "", 53 | "fields": [ 54 | { 55 | "id": "name", 56 | "name": "Name", 57 | "type": "Symbol", 58 | "localized": false, 59 | "required": true, 60 | "validations": [], 61 | "disabled": false, 62 | "omitted": false 63 | }, 64 | { 65 | "id": "title", 66 | "name": "Title", 67 | "type": "Symbol", 68 | "localized": false, 69 | "required": true, 70 | "validations": [], 71 | "disabled": false, 72 | "omitted": false 73 | }, 74 | { 75 | "id": "company", 76 | "name": "Company", 77 | "type": "Symbol", 78 | "localized": false, 79 | "required": true, 80 | "validations": [], 81 | "disabled": false, 82 | "omitted": false 83 | }, 84 | { 85 | "id": "shortBio", 86 | "name": "Short Bio", 87 | "type": "Text", 88 | "localized": false, 89 | "required": true, 90 | "validations": [], 91 | "disabled": false, 92 | "omitted": false 93 | }, 94 | { 95 | "id": "email", 96 | "name": "Email", 97 | "type": "Symbol", 98 | "localized": false, 99 | "required": false, 100 | "validations": [], 101 | "disabled": false, 102 | "omitted": false 103 | }, 104 | { 105 | "id": "phone", 106 | "name": "Phone", 107 | "type": "Symbol", 108 | "localized": false, 109 | "required": false, 110 | "validations": [], 111 | "disabled": false, 112 | "omitted": false 113 | }, 114 | { 115 | "id": "facebook", 116 | "name": "Facebook", 117 | "type": "Symbol", 118 | "localized": false, 119 | "required": false, 120 | "validations": [], 121 | "disabled": false, 122 | "omitted": false 123 | }, 124 | { 125 | "id": "twitter", 126 | "name": "Twitter", 127 | "type": "Symbol", 128 | "localized": false, 129 | "required": false, 130 | "validations": [], 131 | "disabled": false, 132 | "omitted": false 133 | }, 134 | { 135 | "id": "github", 136 | "name": "Github", 137 | "type": "Symbol", 138 | "localized": false, 139 | "required": false, 140 | "validations": [], 141 | "disabled": false, 142 | "omitted": false 143 | }, 144 | { 145 | "id": "image", 146 | "name": "Image", 147 | "type": "Link", 148 | "localized": false, 149 | "required": false, 150 | "validations": [], 151 | "disabled": false, 152 | "omitted": false, 153 | "linkType": "Asset" 154 | } 155 | ] 156 | }, 157 | { 158 | "sys": { 159 | "space": { 160 | "sys": { 161 | "type": "Link", 162 | "linkType": "Space", 163 | "id": "6yhac0bg4wbt" 164 | } 165 | }, 166 | "id": "blogPost", 167 | "type": "ContentType", 168 | "createdAt": "2020-01-12T20:11:27.628Z", 169 | "updatedAt": "2020-01-12T20:11:31.398Z", 170 | "environment": { 171 | "sys": { 172 | "id": "master", 173 | "type": "Link", 174 | "linkType": "Environment" 175 | } 176 | }, 177 | "publishedVersion": 1, 178 | "publishedAt": "2020-01-12T20:11:31.398Z", 179 | "firstPublishedAt": "2020-01-12T20:11:31.398Z", 180 | "createdBy": { 181 | "sys": { 182 | "type": "Link", 183 | "linkType": "User", 184 | "id": "1lkP8MOZgpIuq3eOIdgDou" 185 | } 186 | }, 187 | "updatedBy": { 188 | "sys": { 189 | "type": "Link", 190 | "linkType": "User", 191 | "id": "1lkP8MOZgpIuq3eOIdgDou" 192 | } 193 | }, 194 | "publishedCounter": 1, 195 | "version": 2, 196 | "publishedBy": { 197 | "sys": { 198 | "type": "Link", 199 | "linkType": "User", 200 | "id": "1lkP8MOZgpIuq3eOIdgDou" 201 | } 202 | } 203 | }, 204 | "displayField": "title", 205 | "name": "Blog Post", 206 | "description": "", 207 | "fields": [ 208 | { 209 | "id": "title", 210 | "name": "Title", 211 | "type": "Symbol", 212 | "localized": false, 213 | "required": true, 214 | "validations": [], 215 | "disabled": false, 216 | "omitted": false 217 | }, 218 | { 219 | "id": "slug", 220 | "name": "Slug", 221 | "type": "Symbol", 222 | "localized": false, 223 | "required": true, 224 | "validations": [], 225 | "disabled": false, 226 | "omitted": false 227 | }, 228 | { 229 | "id": "heroImage", 230 | "name": "Hero Image", 231 | "type": "Link", 232 | "localized": false, 233 | "required": true, 234 | "validations": [], 235 | "disabled": false, 236 | "omitted": false, 237 | "linkType": "Asset" 238 | }, 239 | { 240 | "id": "description", 241 | "name": "Description", 242 | "type": "Text", 243 | "localized": false, 244 | "required": true, 245 | "validations": [], 246 | "disabled": false, 247 | "omitted": false 248 | }, 249 | { 250 | "id": "body", 251 | "name": "Body", 252 | "type": "Text", 253 | "localized": false, 254 | "required": true, 255 | "validations": [], 256 | "disabled": false, 257 | "omitted": false 258 | }, 259 | { 260 | "id": "author", 261 | "name": "Author", 262 | "type": "Link", 263 | "localized": false, 264 | "required": false, 265 | "validations": [ 266 | { 267 | "linkContentType": ["person"] 268 | } 269 | ], 270 | "disabled": false, 271 | "omitted": false, 272 | "linkType": "Entry" 273 | }, 274 | { 275 | "id": "publishDate", 276 | "name": "Publish Date", 277 | "type": "Date", 278 | "localized": false, 279 | "required": true, 280 | "validations": [], 281 | "disabled": false, 282 | "omitted": false 283 | }, 284 | { 285 | "id": "tags", 286 | "name": "Tags", 287 | "type": "Array", 288 | "localized": false, 289 | "required": false, 290 | "validations": [], 291 | "disabled": false, 292 | "omitted": false, 293 | "items": { 294 | "type": "Symbol", 295 | "validations": [ 296 | { 297 | "in": ["general", "javascript", "static-sites"] 298 | } 299 | ] 300 | } 301 | } 302 | ] 303 | }, 304 | { 305 | "sys": { 306 | "space": { 307 | "sys": { 308 | "type": "Link", 309 | "linkType": "Space", 310 | "id": "6yhac0bg4wbt" 311 | } 312 | }, 313 | "id": "test", 314 | "type": "ContentType", 315 | "createdAt": "2020-01-13T02:05:34.777Z", 316 | "updatedAt": "2020-01-13T04:23:20.314Z", 317 | "environment": { 318 | "sys": { 319 | "id": "master", 320 | "type": "Link", 321 | "linkType": "Environment" 322 | } 323 | }, 324 | "publishedVersion": 15, 325 | "publishedAt": "2020-01-13T04:23:20.314Z", 326 | "firstPublishedAt": "2020-01-13T02:05:35.031Z", 327 | "createdBy": { 328 | "sys": { 329 | "type": "Link", 330 | "linkType": "User", 331 | "id": "1lkP8MOZgpIuq3eOIdgDou" 332 | } 333 | }, 334 | "updatedBy": { 335 | "sys": { 336 | "type": "Link", 337 | "linkType": "User", 338 | "id": "1lkP8MOZgpIuq3eOIdgDou" 339 | } 340 | }, 341 | "publishedCounter": 8, 342 | "version": 16, 343 | "publishedBy": { 344 | "sys": { 345 | "type": "Link", 346 | "linkType": "User", 347 | "id": "1lkP8MOZgpIuq3eOIdgDou" 348 | } 349 | } 350 | }, 351 | "displayField": "test", 352 | "name": "test", 353 | "description": "", 354 | "fields": [ 355 | { 356 | "id": "test", 357 | "name": "test", 358 | "type": "Symbol", 359 | "localized": false, 360 | "required": false, 361 | "validations": [ 362 | { 363 | "in": [ 364 | "sfjsfdlkj", 365 | "sdf", 366 | "sdfw", 367 | "q3e14", 368 | "123e12", 369 | "asdkasdjk", 370 | "sdkfasdlfksad", 371 | "sadfasdfldaksfdsdfsa", 372 | "sdlknzxcvnmz.xc,nvzx", 373 | "sdflksadfkljawoeqpf" 374 | ] 375 | } 376 | ], 377 | "disabled": false, 378 | "omitted": false 379 | }, 380 | { 381 | "id": "test2", 382 | "name": "test2", 383 | "type": "RichText", 384 | "localized": false, 385 | "required": false, 386 | "validations": [], 387 | "disabled": false, 388 | "omitted": false 389 | }, 390 | { 391 | "id": "test3", 392 | "name": "test3", 393 | "type": "Integer", 394 | "localized": false, 395 | "required": false, 396 | "validations": [], 397 | "disabled": false, 398 | "omitted": false 399 | }, 400 | { 401 | "id": "test4", 402 | "name": "test4", 403 | "type": "Date", 404 | "localized": false, 405 | "required": false, 406 | "validations": [], 407 | "disabled": false, 408 | "omitted": false 409 | }, 410 | { 411 | "id": "test5", 412 | "name": "test5", 413 | "type": "Location", 414 | "localized": false, 415 | "required": false, 416 | "validations": [], 417 | "disabled": false, 418 | "omitted": false 419 | }, 420 | { 421 | "id": "test6", 422 | "name": "test6", 423 | "type": "Link", 424 | "localized": false, 425 | "required": false, 426 | "validations": [], 427 | "disabled": false, 428 | "omitted": false, 429 | "linkType": "Asset" 430 | }, 431 | { 432 | "id": "test7", 433 | "name": "test7", 434 | "type": "Array", 435 | "localized": false, 436 | "required": false, 437 | "validations": [], 438 | "disabled": false, 439 | "omitted": false, 440 | "items": { 441 | "type": "Link", 442 | "validations": [], 443 | "linkType": "Asset" 444 | } 445 | }, 446 | { 447 | "id": "test8", 448 | "name": "test8", 449 | "type": "Boolean", 450 | "localized": false, 451 | "required": false, 452 | "validations": [], 453 | "disabled": false, 454 | "omitted": false 455 | }, 456 | { 457 | "id": "test9", 458 | "name": "test9", 459 | "type": "Object", 460 | "localized": false, 461 | "required": false, 462 | "validations": [], 463 | "disabled": false, 464 | "omitted": false 465 | }, 466 | { 467 | "id": "test10", 468 | "name": "test10", 469 | "type": "Link", 470 | "localized": false, 471 | "required": false, 472 | "validations": [], 473 | "disabled": false, 474 | "omitted": false, 475 | "linkType": "Entry" 476 | }, 477 | { 478 | "id": "test11", 479 | "name": "test11", 480 | "type": "Array", 481 | "localized": false, 482 | "required": false, 483 | "validations": [], 484 | "disabled": false, 485 | "omitted": false, 486 | "items": { 487 | "type": "Link", 488 | "validations": [], 489 | "linkType": "Entry" 490 | } 491 | }, 492 | { 493 | "id": "test12", 494 | "name": "test12", 495 | "type": "Array", 496 | "localized": false, 497 | "required": true, 498 | "validations": [], 499 | "disabled": false, 500 | "omitted": false, 501 | "items": { 502 | "type": "Symbol", 503 | "validations": [] 504 | } 505 | }, 506 | { 507 | "id": "test13", 508 | "name": "test13", 509 | "type": "Text", 510 | "localized": false, 511 | "required": false, 512 | "validations": [], 513 | "disabled": false, 514 | "omitted": false 515 | }, 516 | { 517 | "id": "test15", 518 | "name": "test15", 519 | "type": "Number", 520 | "localized": false, 521 | "required": false, 522 | "validations": [], 523 | "disabled": false, 524 | "omitted": false 525 | }, 526 | { 527 | "id": "test14", 528 | "name": "test 14", 529 | "type": "Symbol", 530 | "localized": false, 531 | "required": false, 532 | "validations": [], 533 | "disabled": false, 534 | "omitted": false 535 | }, 536 | { 537 | "id": "wefijwqefoj", 538 | "name": "wefijwqefoj", 539 | "type": "Symbol", 540 | "localized": false, 541 | "required": false, 542 | "validations": [ 543 | { 544 | "in": [ 545 | "fesjsdf", 546 | "asdofasd", 547 | "wqe0ri", 548 | "we", 549 | "sdf", 550 | "sadf", 551 | "sd", 552 | "sdfsdfasd", 553 | "adsf", 554 | "sadfkii" 555 | ] 556 | } 557 | ], 558 | "disabled": false, 559 | "omitted": false 560 | }, 561 | { 562 | "id": "okok", 563 | "name": "okok", 564 | "type": "Symbol", 565 | "localized": false, 566 | "required": false, 567 | "validations": [], 568 | "disabled": false, 569 | "omitted": false 570 | } 571 | ] 572 | } 573 | ], 574 | "editorInterfaces": [ 575 | { 576 | "sys": { 577 | "id": "default", 578 | "type": "EditorInterface", 579 | "space": { 580 | "sys": { 581 | "id": "6yhac0bg4wbt", 582 | "type": "Link", 583 | "linkType": "Space" 584 | } 585 | }, 586 | "version": 2, 587 | "createdAt": "2020-01-12T20:11:31.113Z", 588 | "createdBy": { 589 | "sys": { 590 | "id": "1lkP8MOZgpIuq3eOIdgDou", 591 | "type": "Link", 592 | "linkType": "User" 593 | } 594 | }, 595 | "updatedAt": "2020-01-12T20:11:31.883Z", 596 | "updatedBy": { 597 | "sys": { 598 | "id": "1lkP8MOZgpIuq3eOIdgDou", 599 | "type": "Link", 600 | "linkType": "User" 601 | } 602 | }, 603 | "contentType": { 604 | "sys": { 605 | "id": "person", 606 | "type": "Link", 607 | "linkType": "ContentType" 608 | } 609 | }, 610 | "environment": { 611 | "sys": { 612 | "id": "master", 613 | "type": "Link", 614 | "linkType": "Environment" 615 | } 616 | } 617 | }, 618 | "controls": [ 619 | { 620 | "fieldId": "name", 621 | "widgetId": "singleLine" 622 | }, 623 | { 624 | "fieldId": "title", 625 | "widgetId": "singleLine" 626 | }, 627 | { 628 | "fieldId": "company", 629 | "widgetId": "singleLine" 630 | }, 631 | { 632 | "fieldId": "shortBio", 633 | "widgetId": "markdown" 634 | }, 635 | { 636 | "fieldId": "email", 637 | "widgetId": "singleLine" 638 | }, 639 | { 640 | "fieldId": "phone", 641 | "widgetId": "singleLine" 642 | }, 643 | { 644 | "fieldId": "facebook", 645 | "widgetId": "singleLine" 646 | }, 647 | { 648 | "fieldId": "twitter", 649 | "widgetId": "singleLine" 650 | }, 651 | { 652 | "fieldId": "github", 653 | "widgetId": "singleLine" 654 | }, 655 | { 656 | "fieldId": "image", 657 | "widgetId": "assetLinkEditor" 658 | } 659 | ] 660 | }, 661 | { 662 | "sys": { 663 | "id": "default", 664 | "type": "EditorInterface", 665 | "space": { 666 | "sys": { 667 | "id": "6yhac0bg4wbt", 668 | "type": "Link", 669 | "linkType": "Space" 670 | } 671 | }, 672 | "version": 2, 673 | "createdAt": "2020-01-12T20:11:31.540Z", 674 | "createdBy": { 675 | "sys": { 676 | "id": "1lkP8MOZgpIuq3eOIdgDou", 677 | "type": "Link", 678 | "linkType": "User" 679 | } 680 | }, 681 | "updatedAt": "2020-01-12T20:11:31.911Z", 682 | "updatedBy": { 683 | "sys": { 684 | "id": "1lkP8MOZgpIuq3eOIdgDou", 685 | "type": "Link", 686 | "linkType": "User" 687 | } 688 | }, 689 | "contentType": { 690 | "sys": { 691 | "id": "blogPost", 692 | "type": "Link", 693 | "linkType": "ContentType" 694 | } 695 | }, 696 | "environment": { 697 | "sys": { 698 | "id": "master", 699 | "type": "Link", 700 | "linkType": "Environment" 701 | } 702 | } 703 | }, 704 | "controls": [ 705 | { 706 | "fieldId": "title", 707 | "widgetId": "singleLine" 708 | }, 709 | { 710 | "fieldId": "slug", 711 | "widgetId": "slugEditor" 712 | }, 713 | { 714 | "fieldId": "heroImage", 715 | "widgetId": "assetLinkEditor" 716 | }, 717 | { 718 | "fieldId": "description", 719 | "widgetId": "markdown" 720 | }, 721 | { 722 | "fieldId": "body", 723 | "widgetId": "markdown" 724 | }, 725 | { 726 | "fieldId": "author", 727 | "widgetId": "entryLinkEditor" 728 | }, 729 | { 730 | "fieldId": "publishDate", 731 | "settings": { 732 | "ampm": "24", 733 | "format": "timeZ" 734 | }, 735 | "widgetId": "datePicker" 736 | }, 737 | { 738 | "fieldId": "tags", 739 | "widgetId": "tagEditor" 740 | } 741 | ] 742 | }, 743 | { 744 | "sys": { 745 | "id": "default", 746 | "type": "EditorInterface", 747 | "space": { 748 | "sys": { 749 | "id": "6yhac0bg4wbt", 750 | "type": "Link", 751 | "linkType": "Space" 752 | } 753 | }, 754 | "version": 16, 755 | "createdAt": "2020-01-13T02:05:35.168Z", 756 | "createdBy": { 757 | "sys": { 758 | "id": "1lkP8MOZgpIuq3eOIdgDou", 759 | "type": "Link", 760 | "linkType": "User" 761 | } 762 | }, 763 | "updatedAt": "2020-01-13T04:23:20.697Z", 764 | "updatedBy": { 765 | "sys": { 766 | "id": "1lkP8MOZgpIuq3eOIdgDou", 767 | "type": "Link", 768 | "linkType": "User" 769 | } 770 | }, 771 | "contentType": { 772 | "sys": { 773 | "id": "test", 774 | "type": "Link", 775 | "linkType": "ContentType" 776 | } 777 | }, 778 | "environment": { 779 | "sys": { 780 | "id": "master", 781 | "type": "Link", 782 | "linkType": "Environment" 783 | } 784 | } 785 | }, 786 | "controls": [ 787 | { 788 | "fieldId": "test", 789 | "settings": { 790 | "helpText": "sdsd" 791 | }, 792 | "widgetId": "dropdown", 793 | "widgetNamespace": "builtin" 794 | }, 795 | { 796 | "fieldId": "test2", 797 | "widgetId": "richTextEditor", 798 | "widgetNamespace": "builtin" 799 | }, 800 | { 801 | "fieldId": "test3", 802 | "widgetId": "numberEditor", 803 | "widgetNamespace": "builtin" 804 | }, 805 | { 806 | "fieldId": "test4", 807 | "widgetId": "datePicker", 808 | "widgetNamespace": "builtin" 809 | }, 810 | { 811 | "fieldId": "test5", 812 | "widgetId": "locationEditor", 813 | "widgetNamespace": "builtin" 814 | }, 815 | { 816 | "fieldId": "test6", 817 | "widgetId": "assetLinkEditor", 818 | "widgetNamespace": "builtin" 819 | }, 820 | { 821 | "fieldId": "test7", 822 | "widgetId": "assetLinksEditor", 823 | "widgetNamespace": "builtin" 824 | }, 825 | { 826 | "fieldId": "test8", 827 | "widgetId": "boolean", 828 | "widgetNamespace": "builtin" 829 | }, 830 | { 831 | "fieldId": "test9", 832 | "widgetId": "objectEditor", 833 | "widgetNamespace": "builtin" 834 | }, 835 | { 836 | "fieldId": "test10", 837 | "widgetId": "entryLinkEditor", 838 | "widgetNamespace": "builtin" 839 | }, 840 | { 841 | "fieldId": "test11", 842 | "widgetId": "entryLinksEditor", 843 | "widgetNamespace": "builtin" 844 | }, 845 | { 846 | "fieldId": "test12", 847 | "widgetId": "tagEditor", 848 | "widgetNamespace": "builtin" 849 | }, 850 | { 851 | "fieldId": "test13", 852 | "widgetId": "markdown", 853 | "widgetNamespace": "builtin" 854 | }, 855 | { 856 | "fieldId": "test15", 857 | "widgetId": "numberEditor", 858 | "widgetNamespace": "builtin" 859 | }, 860 | { 861 | "fieldId": "test14", 862 | "widgetId": "urlEditor", 863 | "widgetNamespace": "builtin" 864 | }, 865 | { 866 | "fieldId": "wefijwqefoj", 867 | "widgetId": "radio", 868 | "widgetNamespace": "builtin" 869 | }, 870 | { 871 | "fieldId": "okok", 872 | "widgetId": "slugEditor", 873 | "widgetNamespace": "builtin" 874 | } 875 | ] 876 | } 877 | ], 878 | "entries": [ 879 | { 880 | "sys": { 881 | "space": { 882 | "sys": { 883 | "type": "Link", 884 | "linkType": "Space", 885 | "id": "6yhac0bg4wbt" 886 | } 887 | }, 888 | "id": "3K9b0esdy0q0yGqgW2g6Ke", 889 | "type": "Entry", 890 | "createdAt": "2020-01-12T20:11:38.918Z", 891 | "updatedAt": "2020-01-12T20:11:42.752Z", 892 | "environment": { 893 | "sys": { 894 | "id": "master", 895 | "type": "Link", 896 | "linkType": "Environment" 897 | } 898 | }, 899 | "publishedVersion": 1, 900 | "publishedAt": "2020-01-12T20:11:42.752Z", 901 | "firstPublishedAt": "2020-01-12T20:11:42.751Z", 902 | "createdBy": { 903 | "sys": { 904 | "type": "Link", 905 | "linkType": "User", 906 | "id": "1lkP8MOZgpIuq3eOIdgDou" 907 | } 908 | }, 909 | "updatedBy": { 910 | "sys": { 911 | "type": "Link", 912 | "linkType": "User", 913 | "id": "1lkP8MOZgpIuq3eOIdgDou" 914 | } 915 | }, 916 | "publishedCounter": 1, 917 | "version": 2, 918 | "publishedBy": { 919 | "sys": { 920 | "type": "Link", 921 | "linkType": "User", 922 | "id": "1lkP8MOZgpIuq3eOIdgDou" 923 | } 924 | }, 925 | "contentType": { 926 | "sys": { 927 | "type": "Link", 928 | "linkType": "ContentType", 929 | "id": "blogPost" 930 | } 931 | } 932 | }, 933 | "fields": { 934 | "title": { 935 | "en-US": "Hello world" 936 | }, 937 | "slug": { 938 | "en-US": "hello-world" 939 | }, 940 | "heroImage": { 941 | "en-US": { 942 | "sys": { 943 | "type": "Link", 944 | "linkType": "Asset", 945 | "id": "6Od9v3wzLOysiMum0Wkmme" 946 | } 947 | } 948 | }, 949 | "description": { 950 | "en-US": "Your very first content with Contentful, pulled in JSON format using the Content Delivery API." 951 | }, 952 | "body": { 953 | "en-US": "These is your very first content with Contentful, pulled in JSON format using the [Content Delivery API](https://www.contentful.com/developers/docs/references/content-delivery-api/ \"Content Delivery API\"). Content and presentation are now decoupled, allowing you to focus your efforts in building the perfect app.\n\n## Your first steps\n\nBuilding with Contentful is easy. First take a moment to get [the basics of content modelling](https://www.contentful.com/r/knowledgebase/content-modelling-basics/ \"the basics of content modelling\"), which you can set up in the [Contentful Web app](https://app.contentful.com/ \"Contentful Web app\"). Once you get that, feel free to drop by the [Documentation](https://www.contentful.com/developers/docs/ \"Documentation\") to learn a bit more about how to build your app with Contentful, in particular the [API basics](https://www.contentful.com/developers/docs/concepts/apis/ \"API basics\") and each one of our four APIs, as shown below.\n\n### Content Delivery API\n\nThe [Content Delivery API](https://www.contentful.com/developers/docs/references/content-delivery-api/ \"Content Delivery API\") (CDA), available at `cdn.contentful.com`, is a read-only API for delivering content from Contentful to apps, websites and other media. Content is delivered as JSON data, and images, videos and other media as files.\nThe API is available via a globally distributed content delivery network. The server closest to the user serves all content, both JSON and binary. This minimizes latency, which especially benefits mobile apps. Hosting content in multiple global data centers also greatly improves the availability of content.\n\n### Content Management API\n\nThe [Content Management API](https://www.contentful.com/developers/docs/references/content-management-api/ \"Content Management API\") (CMA), available at `api.contentful.com`, is a read-write API for managing content. Unlike the Content Delivery API, the management API requires you to authenticate as a Contentful user. You could use the CMA for several use cases, such as:\n* Automatic imports from different CMSes like WordPress or Drupal.\n* Integration with other backend systems, such as an e-commerce shop.\n* Building custom editing experiences. We built the [Contentful Web app](https://app.contentful.com/ \"Contentful Web app\") on top of this API.\n\n### Preview API\n\nThe [Content Preview API](https://www.contentful.com/developers/docs/concepts/apis/#content-preview-api \"Content Preview API\"), available at `preview.contentful.com`, is a variant of the CDA for previewing your content before delivering it to your customers. You use the Content Preview API in combination with a \"preview\" deployment of your website (or a \"preview\" build of your mobile app) that allows content managers and authors to view their work in-context, as if it were published, using a \"preview\" access token as though it were delivered by the CDA.\n\n### Images API\n\nThe [Images API](https://www.contentful.com/developers/docs/concepts/apis/#images-api \"Images API\"), available at `images.contentful.com`, allows you to resize and crop images, change their background color and convert them to different formats. Using our API for these transformations lets you upload high-quality assets, deliver exactly what your app needs, and still get all the benefits of our caching CDN." 954 | }, 955 | "author": { 956 | "en-US": { 957 | "sys": { 958 | "type": "Link", 959 | "linkType": "Entry", 960 | "id": "15jwOBqpxqSAOy2eOO4S0m" 961 | } 962 | } 963 | }, 964 | "publishDate": { 965 | "en-US": "2017-05-15T00:00+02:00" 966 | }, 967 | "tags": { 968 | "en-US": ["general"] 969 | } 970 | } 971 | }, 972 | { 973 | "sys": { 974 | "space": { 975 | "sys": { 976 | "type": "Link", 977 | "linkType": "Space", 978 | "id": "6yhac0bg4wbt" 979 | } 980 | }, 981 | "id": "15jwOBqpxqSAOy2eOO4S0m", 982 | "type": "Entry", 983 | "createdAt": "2020-01-12T20:11:38.920Z", 984 | "updatedAt": "2020-01-12T20:11:42.099Z", 985 | "environment": { 986 | "sys": { 987 | "id": "master", 988 | "type": "Link", 989 | "linkType": "Environment" 990 | } 991 | }, 992 | "publishedVersion": 1, 993 | "publishedAt": "2020-01-12T20:11:42.099Z", 994 | "firstPublishedAt": "2020-01-12T20:11:42.099Z", 995 | "createdBy": { 996 | "sys": { 997 | "type": "Link", 998 | "linkType": "User", 999 | "id": "1lkP8MOZgpIuq3eOIdgDou" 1000 | } 1001 | }, 1002 | "updatedBy": { 1003 | "sys": { 1004 | "type": "Link", 1005 | "linkType": "User", 1006 | "id": "1lkP8MOZgpIuq3eOIdgDou" 1007 | } 1008 | }, 1009 | "publishedCounter": 1, 1010 | "version": 2, 1011 | "publishedBy": { 1012 | "sys": { 1013 | "type": "Link", 1014 | "linkType": "User", 1015 | "id": "1lkP8MOZgpIuq3eOIdgDou" 1016 | } 1017 | }, 1018 | "contentType": { 1019 | "sys": { 1020 | "type": "Link", 1021 | "linkType": "ContentType", 1022 | "id": "person" 1023 | } 1024 | } 1025 | }, 1026 | "fields": { 1027 | "name": { 1028 | "en-US": "John Doe" 1029 | }, 1030 | "title": { 1031 | "en-US": "Web Developer" 1032 | }, 1033 | "company": { 1034 | "en-US": "ACME" 1035 | }, 1036 | "shortBio": { 1037 | "en-US": "Research and recommendations for modern stack websites." 1038 | }, 1039 | "email": { 1040 | "en-US": "john@doe.com" 1041 | }, 1042 | "phone": { 1043 | "en-US": "0176 / 1234567" 1044 | }, 1045 | "facebook": { 1046 | "en-US": "johndoe" 1047 | }, 1048 | "twitter": { 1049 | "en-US": "johndoe" 1050 | }, 1051 | "github": { 1052 | "en-US": "johndoe" 1053 | }, 1054 | "image": { 1055 | "en-US": { 1056 | "sys": { 1057 | "type": "Link", 1058 | "linkType": "Asset", 1059 | "id": "7orLdboQQowIUs22KAW4U" 1060 | } 1061 | } 1062 | } 1063 | } 1064 | }, 1065 | { 1066 | "sys": { 1067 | "space": { 1068 | "sys": { 1069 | "type": "Link", 1070 | "linkType": "Space", 1071 | "id": "6yhac0bg4wbt" 1072 | } 1073 | }, 1074 | "id": "31TNnjHlfaGUoMOwU0M2og", 1075 | "type": "Entry", 1076 | "createdAt": "2020-01-12T20:11:38.930Z", 1077 | "updatedAt": "2020-01-12T20:11:43.261Z", 1078 | "environment": { 1079 | "sys": { 1080 | "id": "master", 1081 | "type": "Link", 1082 | "linkType": "Environment" 1083 | } 1084 | }, 1085 | "publishedVersion": 1, 1086 | "publishedAt": "2020-01-12T20:11:43.261Z", 1087 | "firstPublishedAt": "2020-01-12T20:11:43.261Z", 1088 | "createdBy": { 1089 | "sys": { 1090 | "type": "Link", 1091 | "linkType": "User", 1092 | "id": "1lkP8MOZgpIuq3eOIdgDou" 1093 | } 1094 | }, 1095 | "updatedBy": { 1096 | "sys": { 1097 | "type": "Link", 1098 | "linkType": "User", 1099 | "id": "1lkP8MOZgpIuq3eOIdgDou" 1100 | } 1101 | }, 1102 | "publishedCounter": 1, 1103 | "version": 2, 1104 | "publishedBy": { 1105 | "sys": { 1106 | "type": "Link", 1107 | "linkType": "User", 1108 | "id": "1lkP8MOZgpIuq3eOIdgDou" 1109 | } 1110 | }, 1111 | "contentType": { 1112 | "sys": { 1113 | "type": "Link", 1114 | "linkType": "ContentType", 1115 | "id": "blogPost" 1116 | } 1117 | } 1118 | }, 1119 | "fields": { 1120 | "title": { 1121 | "en-US": "Automate with webhooks" 1122 | }, 1123 | "slug": { 1124 | "en-US": "automate-with-webhooks" 1125 | }, 1126 | "heroImage": { 1127 | "en-US": { 1128 | "sys": { 1129 | "type": "Link", 1130 | "linkType": "Asset", 1131 | "id": "4shwYI3POEGkw0Eg6kcyaQ" 1132 | } 1133 | } 1134 | }, 1135 | "description": { 1136 | "en-US": "Webhooks notify you, another person or system when resources have changed by calling a given HTTP endpoint." 1137 | }, 1138 | "body": { 1139 | "en-US": "## What are webhooks?\n\nThe webhooks are used to notify you when content has been changed. Specify a URL, configure your webhook, and we will send an HTTP POST request whenever something happens to your content.\n\n## How do I configure a webhook?\n\nGo to Settings → Webhooks from the navigation bar at the top. From there, hit Add webhook, and you will be directed to your new webhook. Then choose a name, put in the information of your HTTP endpoint (URL and authentication), specify any custom headers and select the types of events that should trigger the webhook.\n\n## Why do I get an old version in the CDA?\n\nAs the delivery API is powered by a CDN network consisting of hundreds of servers distributed across continents, it takes some time (up to a few minutes) to reflect the changes to the published content. This must be taken into consideration when reacting to webhooks. In normal conditions, there could be a reasonable delay of 2 to 5 minutes.\n\nExtracted from the [Webhooks FAQ](https://www.contentful.com/faq/webhooks/ \"Webhooks FAQ\")." 1140 | }, 1141 | "author": { 1142 | "en-US": { 1143 | "sys": { 1144 | "type": "Link", 1145 | "linkType": "Entry", 1146 | "id": "15jwOBqpxqSAOy2eOO4S0m" 1147 | } 1148 | } 1149 | }, 1150 | "publishDate": { 1151 | "en-US": "2017-05-12T00:00+02:00" 1152 | }, 1153 | "tags": { 1154 | "en-US": ["javascript"] 1155 | } 1156 | } 1157 | }, 1158 | { 1159 | "sys": { 1160 | "space": { 1161 | "sys": { 1162 | "type": "Link", 1163 | "linkType": "Space", 1164 | "id": "6yhac0bg4wbt" 1165 | } 1166 | }, 1167 | "id": "2PtC9h1YqIA6kaUaIsWEQ0", 1168 | "type": "Entry", 1169 | "createdAt": "2020-01-12T20:11:38.934Z", 1170 | "updatedAt": "2020-01-12T20:11:42.399Z", 1171 | "environment": { 1172 | "sys": { 1173 | "id": "master", 1174 | "type": "Link", 1175 | "linkType": "Environment" 1176 | } 1177 | }, 1178 | "publishedVersion": 1, 1179 | "publishedAt": "2020-01-12T20:11:42.399Z", 1180 | "firstPublishedAt": "2020-01-12T20:11:42.399Z", 1181 | "createdBy": { 1182 | "sys": { 1183 | "type": "Link", 1184 | "linkType": "User", 1185 | "id": "1lkP8MOZgpIuq3eOIdgDou" 1186 | } 1187 | }, 1188 | "updatedBy": { 1189 | "sys": { 1190 | "type": "Link", 1191 | "linkType": "User", 1192 | "id": "1lkP8MOZgpIuq3eOIdgDou" 1193 | } 1194 | }, 1195 | "publishedCounter": 1, 1196 | "version": 2, 1197 | "publishedBy": { 1198 | "sys": { 1199 | "type": "Link", 1200 | "linkType": "User", 1201 | "id": "1lkP8MOZgpIuq3eOIdgDou" 1202 | } 1203 | }, 1204 | "contentType": { 1205 | "sys": { 1206 | "type": "Link", 1207 | "linkType": "ContentType", 1208 | "id": "blogPost" 1209 | } 1210 | } 1211 | }, 1212 | "fields": { 1213 | "title": { 1214 | "en-US": "Static sites are great" 1215 | }, 1216 | "slug": { 1217 | "en-US": "static-sites-are-great" 1218 | }, 1219 | "heroImage": { 1220 | "en-US": { 1221 | "sys": { 1222 | "type": "Link", 1223 | "linkType": "Asset", 1224 | "id": "4NzwDSDlGECGIiokKomsyI" 1225 | } 1226 | } 1227 | }, 1228 | "description": { 1229 | "en-US": "Worry less about security, caching, and talking to the server. Static sites are the new thing." 1230 | }, 1231 | "body": { 1232 | "en-US": "## The case for the static site generator\n\nMore and more developers are jumping on the \"go static train\", and rightfully so. Static pages are fast, lightweight, they scale well. They are more secure, and simple to maintain and they allow you to focus all your time and effort on the user interface. Often times, this dedication really shows.\n\nIt just so happens that static site generators are mostly loved by developers, but not by the average Joe. They do not offer WYSIWYG, previewing on demo sites may take an update cycle, they are often based on markdown text files, and they require some knowledge of modern day repositories.\n\nMoreover, when teams are collaborating, it can get complicated quickly. Has this article already been proof-read or reviewed? Is this input valid? Are user permissions available, e.g. for administering adding and removing team members? Can this article be published at a future date? How can a large repository of content be categorized, organized, and searched? All these requirements have previously been more or less solved within the admin area of your CMS. But of course with all the baggage that made you leave the appserver-app-database-in-one-big-blob stack in the first place.\n\n## Content APIs to the rescue\n\nAn alternative is decoupling the content management aspect from the system. And then replacing the maintenance prone server with a cloud based web service offering. Effectively, instead of your CMS of old, you move to a [Content Management as a Service (CMaaS)](https://www.contentful.com/r/knowledgebase/content-as-a-service/ \"Content Management as a Service (CMaaS)\") world, with a content API to deliver all your content. That way, you get the all the [benefits of content management features](http://www.digett.com/blog/01/16/2014/pairing-static-websites-cms \"benefits of content management features\") while still being able to embrace the static site generator mantra.\n\nIt so happens that Contentful is offering just that kind of content API. A service that\n\n* from the ground up has been designed to be fast, scalable, secure, and offer high uptime, so that you don’t have to worry about maintenance ever again.\n* offers a powerful editor and lots of flexibility in creating templates for your documents that your editors can reuse and combine, so that no developers resources are required in everyday writing and updating tasks.\n* separates content from presentation, so you can reuse your content repository for any device platform your heart desires. That way, you can COPE (\"create once, publish everywhere\").\n* offers webhooks that you can use to rebuild your static site in a fully automated fashion every time your content is modified.\n\nExtracted from the article [CMS-functionality for static site generators](https://www.contentful.com/r/knowledgebase/contentful-api-cms-static-site-generators/ \"CMS-functionality for static site generators\"). Read more about the [static site generators supported by Contentful](https://www.contentful.com/developers/docs/tools/staticsitegenerators/ \"static site generators supported by Contentful\")." 1233 | }, 1234 | "author": { 1235 | "en-US": { 1236 | "sys": { 1237 | "type": "Link", 1238 | "linkType": "Entry", 1239 | "id": "15jwOBqpxqSAOy2eOO4S0m" 1240 | } 1241 | } 1242 | }, 1243 | "publishDate": { 1244 | "en-US": "2017-05-16T00:00+02:00" 1245 | }, 1246 | "tags": { 1247 | "en-US": ["javascript", "static-sites"] 1248 | } 1249 | } 1250 | }, 1251 | { 1252 | "sys": { 1253 | "space": { 1254 | "sys": { 1255 | "type": "Link", 1256 | "linkType": "Space", 1257 | "id": "6yhac0bg4wbt" 1258 | } 1259 | }, 1260 | "id": "6pkhnmE2tV7yCrQy6z8t3k", 1261 | "type": "Entry", 1262 | "createdAt": "2020-01-13T04:16:22.073Z", 1263 | "updatedAt": "2020-01-13T04:24:42.590Z", 1264 | "environment": { 1265 | "sys": { 1266 | "id": "master", 1267 | "type": "Link", 1268 | "linkType": "Environment" 1269 | } 1270 | }, 1271 | "publishedVersion": 63, 1272 | "publishedAt": "2020-01-13T04:24:42.590Z", 1273 | "firstPublishedAt": "2020-01-13T04:24:42.590Z", 1274 | "createdBy": { 1275 | "sys": { 1276 | "type": "Link", 1277 | "linkType": "User", 1278 | "id": "1lkP8MOZgpIuq3eOIdgDou" 1279 | } 1280 | }, 1281 | "updatedBy": { 1282 | "sys": { 1283 | "type": "Link", 1284 | "linkType": "User", 1285 | "id": "1lkP8MOZgpIuq3eOIdgDou" 1286 | } 1287 | }, 1288 | "publishedCounter": 1, 1289 | "version": 64, 1290 | "publishedBy": { 1291 | "sys": { 1292 | "type": "Link", 1293 | "linkType": "User", 1294 | "id": "1lkP8MOZgpIuq3eOIdgDou" 1295 | } 1296 | }, 1297 | "contentType": { 1298 | "sys": { 1299 | "type": "Link", 1300 | "linkType": "ContentType", 1301 | "id": "test" 1302 | } 1303 | } 1304 | }, 1305 | "fields": { 1306 | "test": { 1307 | "en-US": "q3e14" 1308 | }, 1309 | "test2": { 1310 | "en-US": { 1311 | "data": {}, 1312 | "content": [ 1313 | { 1314 | "data": {}, 1315 | "content": [ 1316 | { 1317 | "data": {}, 1318 | "marks": [], 1319 | "value": "asfweqqwf", 1320 | "nodeType": "text" 1321 | } 1322 | ], 1323 | "nodeType": "paragraph" 1324 | }, 1325 | { 1326 | "data": {}, 1327 | "content": [ 1328 | { 1329 | "data": {}, 1330 | "marks": [], 1331 | "value": "", 1332 | "nodeType": "text" 1333 | } 1334 | ], 1335 | "nodeType": "paragraph" 1336 | }, 1337 | { 1338 | "data": {}, 1339 | "content": [ 1340 | { 1341 | "data": {}, 1342 | "marks": [ 1343 | { 1344 | "type": "bold" 1345 | } 1346 | ], 1347 | "value": "oojdfosf", 1348 | "nodeType": "text" 1349 | } 1350 | ], 1351 | "nodeType": "paragraph" 1352 | }, 1353 | { 1354 | "data": {}, 1355 | "content": [ 1356 | { 1357 | "data": {}, 1358 | "marks": [ 1359 | { 1360 | "type": "bold" 1361 | } 1362 | ], 1363 | "value": "", 1364 | "nodeType": "text" 1365 | } 1366 | ], 1367 | "nodeType": "paragraph" 1368 | }, 1369 | { 1370 | "data": {}, 1371 | "content": [ 1372 | { 1373 | "data": {}, 1374 | "marks": [ 1375 | { 1376 | "type": "bold" 1377 | }, 1378 | { 1379 | "type": "italic" 1380 | } 1381 | ], 1382 | "value": "oojoj", 1383 | "nodeType": "text" 1384 | } 1385 | ], 1386 | "nodeType": "paragraph" 1387 | }, 1388 | { 1389 | "data": {}, 1390 | "content": [ 1391 | { 1392 | "data": {}, 1393 | "marks": [ 1394 | { 1395 | "type": "bold" 1396 | }, 1397 | { 1398 | "type": "italic" 1399 | }, 1400 | { 1401 | "type": "underline" 1402 | } 1403 | ], 1404 | "value": "nononon", 1405 | "nodeType": "text" 1406 | } 1407 | ], 1408 | "nodeType": "paragraph" 1409 | }, 1410 | { 1411 | "data": {}, 1412 | "content": [ 1413 | { 1414 | "data": {}, 1415 | "marks": [ 1416 | { 1417 | "type": "bold" 1418 | }, 1419 | { 1420 | "type": "italic" 1421 | }, 1422 | { 1423 | "type": "underline" 1424 | }, 1425 | { 1426 | "type": "code" 1427 | } 1428 | ], 1429 | "value": "osfadjsdfs", 1430 | "nodeType": "text" 1431 | } 1432 | ], 1433 | "nodeType": "paragraph" 1434 | }, 1435 | { 1436 | "data": {}, 1437 | "content": [ 1438 | { 1439 | "data": {}, 1440 | "marks": [ 1441 | { 1442 | "type": "bold" 1443 | }, 1444 | { 1445 | "type": "italic" 1446 | }, 1447 | { 1448 | "type": "underline" 1449 | }, 1450 | { 1451 | "type": "code" 1452 | } 1453 | ], 1454 | "value": "asdfkljsad", 1455 | "nodeType": "text" 1456 | } 1457 | ], 1458 | "nodeType": "paragraph" 1459 | }, 1460 | { 1461 | "data": {}, 1462 | "content": [ 1463 | { 1464 | "data": {}, 1465 | "marks": [ 1466 | { 1467 | "type": "bold" 1468 | }, 1469 | { 1470 | "type": "italic" 1471 | }, 1472 | { 1473 | "type": "underline" 1474 | }, 1475 | { 1476 | "type": "code" 1477 | } 1478 | ], 1479 | "value": "sadflk", 1480 | "nodeType": "text" 1481 | } 1482 | ], 1483 | "nodeType": "paragraph" 1484 | }, 1485 | { 1486 | "data": {}, 1487 | "content": [ 1488 | { 1489 | "data": {}, 1490 | "marks": [ 1491 | { 1492 | "type": "bold" 1493 | }, 1494 | { 1495 | "type": "italic" 1496 | }, 1497 | { 1498 | "type": "underline" 1499 | }, 1500 | { 1501 | "type": "code" 1502 | } 1503 | ], 1504 | "value": "", 1505 | "nodeType": "text" 1506 | } 1507 | ], 1508 | "nodeType": "paragraph" 1509 | }, 1510 | { 1511 | "data": {}, 1512 | "content": [ 1513 | { 1514 | "data": {}, 1515 | "marks": [ 1516 | { 1517 | "type": "bold" 1518 | }, 1519 | { 1520 | "type": "italic" 1521 | }, 1522 | { 1523 | "type": "underline" 1524 | }, 1525 | { 1526 | "type": "code" 1527 | } 1528 | ], 1529 | "value": "", 1530 | "nodeType": "text" 1531 | }, 1532 | { 1533 | "data": { 1534 | "uri": "https://google.com" 1535 | }, 1536 | "content": [ 1537 | { 1538 | "data": {}, 1539 | "marks": [ 1540 | { 1541 | "type": "bold" 1542 | }, 1543 | { 1544 | "type": "italic" 1545 | }, 1546 | { 1547 | "type": "underline" 1548 | }, 1549 | { 1550 | "type": "code" 1551 | } 1552 | ], 1553 | "value": "goog", 1554 | "nodeType": "text" 1555 | } 1556 | ], 1557 | "nodeType": "hyperlink" 1558 | }, 1559 | { 1560 | "data": {}, 1561 | "marks": [ 1562 | { 1563 | "type": "bold" 1564 | }, 1565 | { 1566 | "type": "italic" 1567 | }, 1568 | { 1569 | "type": "underline" 1570 | }, 1571 | { 1572 | "type": "code" 1573 | } 1574 | ], 1575 | "value": "", 1576 | "nodeType": "text" 1577 | } 1578 | ], 1579 | "nodeType": "paragraph" 1580 | }, 1581 | { 1582 | "data": {}, 1583 | "content": [ 1584 | { 1585 | "data": {}, 1586 | "marks": [ 1587 | { 1588 | "type": "bold" 1589 | }, 1590 | { 1591 | "type": "italic" 1592 | }, 1593 | { 1594 | "type": "underline" 1595 | }, 1596 | { 1597 | "type": "code" 1598 | } 1599 | ], 1600 | "value": "", 1601 | "nodeType": "text" 1602 | } 1603 | ], 1604 | "nodeType": "paragraph" 1605 | }, 1606 | { 1607 | "data": {}, 1608 | "content": [ 1609 | { 1610 | "data": {}, 1611 | "marks": [ 1612 | { 1613 | "type": "bold" 1614 | }, 1615 | { 1616 | "type": "italic" 1617 | }, 1618 | { 1619 | "type": "underline" 1620 | }, 1621 | { 1622 | "type": "code" 1623 | } 1624 | ], 1625 | "value": "", 1626 | "nodeType": "text" 1627 | }, 1628 | { 1629 | "data": { 1630 | "target": { 1631 | "sys": { 1632 | "id": "7orLdboQQowIUs22KAW4U", 1633 | "type": "Link", 1634 | "linkType": "Asset" 1635 | } 1636 | } 1637 | }, 1638 | "content": [ 1639 | { 1640 | "data": {}, 1641 | "marks": [ 1642 | { 1643 | "type": "bold" 1644 | }, 1645 | { 1646 | "type": "italic" 1647 | }, 1648 | { 1649 | "type": "underline" 1650 | }, 1651 | { 1652 | "type": "code" 1653 | } 1654 | ], 1655 | "value": "olfjsdo", 1656 | "nodeType": "text" 1657 | } 1658 | ], 1659 | "nodeType": "asset-hyperlink" 1660 | }, 1661 | { 1662 | "data": {}, 1663 | "marks": [ 1664 | { 1665 | "type": "bold" 1666 | }, 1667 | { 1668 | "type": "italic" 1669 | }, 1670 | { 1671 | "type": "underline" 1672 | }, 1673 | { 1674 | "type": "code" 1675 | } 1676 | ], 1677 | "value": "", 1678 | "nodeType": "text" 1679 | } 1680 | ], 1681 | "nodeType": "paragraph" 1682 | }, 1683 | { 1684 | "data": {}, 1685 | "content": [ 1686 | { 1687 | "data": {}, 1688 | "marks": [ 1689 | { 1690 | "type": "bold" 1691 | }, 1692 | { 1693 | "type": "italic" 1694 | }, 1695 | { 1696 | "type": "underline" 1697 | }, 1698 | { 1699 | "type": "code" 1700 | } 1701 | ], 1702 | "value": "", 1703 | "nodeType": "text" 1704 | } 1705 | ], 1706 | "nodeType": "paragraph" 1707 | }, 1708 | { 1709 | "data": {}, 1710 | "content": [ 1711 | { 1712 | "data": {}, 1713 | "marks": [ 1714 | { 1715 | "type": "bold" 1716 | }, 1717 | { 1718 | "type": "italic" 1719 | }, 1720 | { 1721 | "type": "underline" 1722 | }, 1723 | { 1724 | "type": "code" 1725 | } 1726 | ], 1727 | "value": "aodsjsdfsdf", 1728 | "nodeType": "text" 1729 | } 1730 | ], 1731 | "nodeType": "paragraph" 1732 | }, 1733 | { 1734 | "data": {}, 1735 | "content": [ 1736 | { 1737 | "data": {}, 1738 | "marks": [ 1739 | { 1740 | "type": "bold" 1741 | }, 1742 | { 1743 | "type": "italic" 1744 | }, 1745 | { 1746 | "type": "underline" 1747 | }, 1748 | { 1749 | "type": "code" 1750 | } 1751 | ], 1752 | "value": "", 1753 | "nodeType": "text" 1754 | } 1755 | ], 1756 | "nodeType": "paragraph" 1757 | }, 1758 | { 1759 | "data": {}, 1760 | "content": [], 1761 | "nodeType": "hr" 1762 | }, 1763 | { 1764 | "data": {}, 1765 | "content": [ 1766 | { 1767 | "data": {}, 1768 | "content": [ 1769 | { 1770 | "data": {}, 1771 | "content": [ 1772 | { 1773 | "data": {}, 1774 | "marks": [], 1775 | "value": "oooojoj", 1776 | "nodeType": "text" 1777 | } 1778 | ], 1779 | "nodeType": "paragraph" 1780 | } 1781 | ], 1782 | "nodeType": "list-item" 1783 | } 1784 | ], 1785 | "nodeType": "unordered-list" 1786 | }, 1787 | { 1788 | "data": {}, 1789 | "content": [ 1790 | { 1791 | "data": {}, 1792 | "content": [ 1793 | { 1794 | "data": {}, 1795 | "content": [ 1796 | { 1797 | "data": {}, 1798 | "marks": [], 1799 | "value": "oj", 1800 | "nodeType": "text" 1801 | } 1802 | ], 1803 | "nodeType": "paragraph" 1804 | } 1805 | ], 1806 | "nodeType": "list-item" 1807 | }, 1808 | { 1809 | "data": {}, 1810 | "content": [ 1811 | { 1812 | "data": {}, 1813 | "content": [ 1814 | { 1815 | "data": {}, 1816 | "marks": [], 1817 | "value": "oj", 1818 | "nodeType": "text" 1819 | } 1820 | ], 1821 | "nodeType": "paragraph" 1822 | } 1823 | ], 1824 | "nodeType": "list-item" 1825 | }, 1826 | { 1827 | "data": {}, 1828 | "content": [ 1829 | { 1830 | "data": {}, 1831 | "content": [ 1832 | { 1833 | "data": {}, 1834 | "marks": [], 1835 | "value": "ojoj", 1836 | "nodeType": "text" 1837 | } 1838 | ], 1839 | "nodeType": "heading-3" 1840 | }, 1841 | { 1842 | "data": { 1843 | "target": { 1844 | "sys": { 1845 | "id": "4NzwDSDlGECGIiokKomsyI", 1846 | "type": "Link", 1847 | "linkType": "Asset" 1848 | } 1849 | } 1850 | }, 1851 | "content": [], 1852 | "nodeType": "embedded-asset-block" 1853 | }, 1854 | { 1855 | "data": {}, 1856 | "content": [ 1857 | { 1858 | "data": {}, 1859 | "marks": [], 1860 | "value": "", 1861 | "nodeType": "text" 1862 | } 1863 | ], 1864 | "nodeType": "paragraph" 1865 | } 1866 | ], 1867 | "nodeType": "list-item" 1868 | } 1869 | ], 1870 | "nodeType": "ordered-list" 1871 | }, 1872 | { 1873 | "data": {}, 1874 | "content": [ 1875 | { 1876 | "data": {}, 1877 | "marks": [], 1878 | "value": "", 1879 | "nodeType": "text" 1880 | } 1881 | ], 1882 | "nodeType": "paragraph" 1883 | } 1884 | ], 1885 | "nodeType": "document" 1886 | } 1887 | }, 1888 | "test3": { 1889 | "en-US": -3 1890 | }, 1891 | "test4": { 1892 | "en-US": "2020-01-16T03:30-05:00" 1893 | }, 1894 | "test5": { 1895 | "en-US": { 1896 | "lon": 13.971457124374993, 1897 | "lat": 51.65104304372601 1898 | } 1899 | }, 1900 | "test6": { 1901 | "en-US": { 1902 | "sys": { 1903 | "type": "Link", 1904 | "linkType": "Asset", 1905 | "id": "4NzwDSDlGECGIiokKomsyI" 1906 | } 1907 | } 1908 | }, 1909 | "test7": { 1910 | "en-US": [ 1911 | { 1912 | "sys": { 1913 | "type": "Link", 1914 | "linkType": "Asset", 1915 | "id": "6Od9v3wzLOysiMum0Wkmme" 1916 | } 1917 | }, 1918 | { 1919 | "sys": { 1920 | "type": "Link", 1921 | "linkType": "Asset", 1922 | "id": "4NzwDSDlGECGIiokKomsyI" 1923 | } 1924 | }, 1925 | { 1926 | "sys": { 1927 | "type": "Link", 1928 | "linkType": "Asset", 1929 | "id": "4shwYI3POEGkw0Eg6kcyaQ" 1930 | } 1931 | }, 1932 | { 1933 | "sys": { 1934 | "type": "Link", 1935 | "linkType": "Asset", 1936 | "id": "7orLdboQQowIUs22KAW4U" 1937 | } 1938 | } 1939 | ] 1940 | }, 1941 | "test8": { 1942 | "en-US": true 1943 | }, 1944 | "test9": { 1945 | "en-US": { 1946 | "a": 1 1947 | } 1948 | }, 1949 | "test10": { 1950 | "en-US": { 1951 | "sys": { 1952 | "type": "Link", 1953 | "linkType": "Entry", 1954 | "id": "3K9b0esdy0q0yGqgW2g6Ke" 1955 | } 1956 | } 1957 | }, 1958 | "test11": { 1959 | "en-US": [ 1960 | { 1961 | "sys": { 1962 | "type": "Link", 1963 | "linkType": "Entry", 1964 | "id": "31TNnjHlfaGUoMOwU0M2og" 1965 | } 1966 | }, 1967 | { 1968 | "sys": { 1969 | "type": "Link", 1970 | "linkType": "Entry", 1971 | "id": "2PtC9h1YqIA6kaUaIsWEQ0" 1972 | } 1973 | }, 1974 | { 1975 | "sys": { 1976 | "type": "Link", 1977 | "linkType": "Entry", 1978 | "id": "15jwOBqpxqSAOy2eOO4S0m" 1979 | } 1980 | }, 1981 | { 1982 | "sys": { 1983 | "type": "Link", 1984 | "linkType": "Entry", 1985 | "id": "3K9b0esdy0q0yGqgW2g6Ke" 1986 | } 1987 | }, 1988 | { 1989 | "sys": { 1990 | "type": "Link", 1991 | "linkType": "Entry", 1992 | "id": "31TNnjHlfaGUoMOwU0M2og" 1993 | } 1994 | } 1995 | ] 1996 | }, 1997 | "test12": { 1998 | "en-US": ["ok", "okj", "ojoij", "plpl", "plplpl"] 1999 | }, 2000 | "test13": { 2001 | "en-US": "asdfasdfqefwsdaZCDS" 2002 | }, 2003 | "test15": { 2004 | "en-US": 53.3 2005 | }, 2006 | "test14": { 2007 | "en-US": "2131ojom" 2008 | }, 2009 | "wefijwqefoj": { 2010 | "en-US": "asdofasd" 2011 | }, 2012 | "okok": { 2013 | "en-US": "q3e14" 2014 | } 2015 | } 2016 | } 2017 | ], 2018 | "assets": [ 2019 | { 2020 | "sys": { 2021 | "space": { 2022 | "sys": { 2023 | "type": "Link", 2024 | "linkType": "Space", 2025 | "id": "6yhac0bg4wbt" 2026 | } 2027 | }, 2028 | "id": "6Od9v3wzLOysiMum0Wkmme", 2029 | "type": "Asset", 2030 | "createdAt": "2020-01-12T20:11:32.156Z", 2031 | "updatedAt": "2020-01-12T20:11:38.564Z", 2032 | "environment": { 2033 | "sys": { 2034 | "id": "master", 2035 | "type": "Link", 2036 | "linkType": "Environment" 2037 | } 2038 | }, 2039 | "publishedVersion": 2, 2040 | "publishedAt": "2020-01-12T20:11:38.564Z", 2041 | "firstPublishedAt": "2020-01-12T20:11:38.564Z", 2042 | "createdBy": { 2043 | "sys": { 2044 | "type": "Link", 2045 | "linkType": "User", 2046 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2047 | } 2048 | }, 2049 | "updatedBy": { 2050 | "sys": { 2051 | "type": "Link", 2052 | "linkType": "User", 2053 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2054 | } 2055 | }, 2056 | "publishedCounter": 1, 2057 | "version": 3, 2058 | "publishedBy": { 2059 | "sys": { 2060 | "type": "Link", 2061 | "linkType": "User", 2062 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2063 | } 2064 | } 2065 | }, 2066 | "fields": { 2067 | "title": { 2068 | "en-US": "Woman with black hat" 2069 | }, 2070 | "description": { 2071 | "en-US": "Woman wearing a black hat" 2072 | }, 2073 | "file": { 2074 | "en-US": { 2075 | "url": "//images.ctfassets.net/6yhac0bg4wbt/6Od9v3wzLOysiMum0Wkmme/9049273464ac850227d5949c4b21ab70/cameron-kirby-88711.jpg", 2076 | "details": { 2077 | "size": 7316629, 2078 | "image": { 2079 | "width": 3000, 2080 | "height": 2000 2081 | } 2082 | }, 2083 | "fileName": "cameron-kirby-88711.jpg", 2084 | "contentType": "image/jpeg" 2085 | } 2086 | } 2087 | } 2088 | }, 2089 | { 2090 | "sys": { 2091 | "space": { 2092 | "sys": { 2093 | "type": "Link", 2094 | "linkType": "Space", 2095 | "id": "6yhac0bg4wbt" 2096 | } 2097 | }, 2098 | "id": "4shwYI3POEGkw0Eg6kcyaQ", 2099 | "type": "Asset", 2100 | "createdAt": "2020-01-12T20:11:32.160Z", 2101 | "updatedAt": "2020-01-12T20:11:38.155Z", 2102 | "environment": { 2103 | "sys": { 2104 | "id": "master", 2105 | "type": "Link", 2106 | "linkType": "Environment" 2107 | } 2108 | }, 2109 | "publishedVersion": 2, 2110 | "publishedAt": "2020-01-12T20:11:38.155Z", 2111 | "firstPublishedAt": "2020-01-12T20:11:38.155Z", 2112 | "createdBy": { 2113 | "sys": { 2114 | "type": "Link", 2115 | "linkType": "User", 2116 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2117 | } 2118 | }, 2119 | "updatedBy": { 2120 | "sys": { 2121 | "type": "Link", 2122 | "linkType": "User", 2123 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2124 | } 2125 | }, 2126 | "publishedCounter": 1, 2127 | "version": 3, 2128 | "publishedBy": { 2129 | "sys": { 2130 | "type": "Link", 2131 | "linkType": "User", 2132 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2133 | } 2134 | } 2135 | }, 2136 | "fields": { 2137 | "title": { 2138 | "en-US": "Man in the fields" 2139 | }, 2140 | "description": { 2141 | "en-US": "Tattooed man walking in a field" 2142 | }, 2143 | "file": { 2144 | "en-US": { 2145 | "url": "//images.ctfassets.net/6yhac0bg4wbt/4shwYI3POEGkw0Eg6kcyaQ/3e0c54ca902e58170c8dfee7d6d292c1/felix-russell-saw-112140.jpg", 2146 | "details": { 2147 | "size": 4539181, 2148 | "image": { 2149 | "width": 2500, 2150 | "height": 1667 2151 | } 2152 | }, 2153 | "fileName": "felix-russell-saw-112140.jpg", 2154 | "contentType": "image/jpeg" 2155 | } 2156 | } 2157 | } 2158 | }, 2159 | { 2160 | "sys": { 2161 | "space": { 2162 | "sys": { 2163 | "type": "Link", 2164 | "linkType": "Space", 2165 | "id": "6yhac0bg4wbt" 2166 | } 2167 | }, 2168 | "id": "7orLdboQQowIUs22KAW4U", 2169 | "type": "Asset", 2170 | "createdAt": "2020-01-12T20:11:32.166Z", 2171 | "updatedAt": "2020-01-12T20:11:37.861Z", 2172 | "environment": { 2173 | "sys": { 2174 | "id": "master", 2175 | "type": "Link", 2176 | "linkType": "Environment" 2177 | } 2178 | }, 2179 | "publishedVersion": 2, 2180 | "publishedAt": "2020-01-12T20:11:37.861Z", 2181 | "firstPublishedAt": "2020-01-12T20:11:37.861Z", 2182 | "createdBy": { 2183 | "sys": { 2184 | "type": "Link", 2185 | "linkType": "User", 2186 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2187 | } 2188 | }, 2189 | "updatedBy": { 2190 | "sys": { 2191 | "type": "Link", 2192 | "linkType": "User", 2193 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2194 | } 2195 | }, 2196 | "publishedCounter": 1, 2197 | "version": 3, 2198 | "publishedBy": { 2199 | "sys": { 2200 | "type": "Link", 2201 | "linkType": "User", 2202 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2203 | } 2204 | } 2205 | }, 2206 | "fields": { 2207 | "title": { 2208 | "en-US": "Sparkler" 2209 | }, 2210 | "description": { 2211 | "en-US": "John with Sparkler" 2212 | }, 2213 | "file": { 2214 | "en-US": { 2215 | "url": "//images.ctfassets.net/6yhac0bg4wbt/7orLdboQQowIUs22KAW4U/538f945e8f3416d9e2eee7a0f4b7ae47/matt-palmer-254999.jpg", 2216 | "details": { 2217 | "size": 2293094, 2218 | "image": { 2219 | "width": 3000, 2220 | "height": 2000 2221 | } 2222 | }, 2223 | "fileName": "matt-palmer-254999.jpg", 2224 | "contentType": "image/jpeg" 2225 | } 2226 | } 2227 | } 2228 | }, 2229 | { 2230 | "sys": { 2231 | "space": { 2232 | "sys": { 2233 | "type": "Link", 2234 | "linkType": "Space", 2235 | "id": "6yhac0bg4wbt" 2236 | } 2237 | }, 2238 | "id": "4NzwDSDlGECGIiokKomsyI", 2239 | "type": "Asset", 2240 | "createdAt": "2020-01-12T20:11:32.170Z", 2241 | "updatedAt": "2020-01-12T20:11:38.391Z", 2242 | "environment": { 2243 | "sys": { 2244 | "id": "master", 2245 | "type": "Link", 2246 | "linkType": "Environment" 2247 | } 2248 | }, 2249 | "publishedVersion": 2, 2250 | "publishedAt": "2020-01-12T20:11:38.391Z", 2251 | "firstPublishedAt": "2020-01-12T20:11:38.391Z", 2252 | "createdBy": { 2253 | "sys": { 2254 | "type": "Link", 2255 | "linkType": "User", 2256 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2257 | } 2258 | }, 2259 | "updatedBy": { 2260 | "sys": { 2261 | "type": "Link", 2262 | "linkType": "User", 2263 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2264 | } 2265 | }, 2266 | "publishedCounter": 1, 2267 | "version": 3, 2268 | "publishedBy": { 2269 | "sys": { 2270 | "type": "Link", 2271 | "linkType": "User", 2272 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2273 | } 2274 | } 2275 | }, 2276 | "fields": { 2277 | "title": { 2278 | "en-US": "City" 2279 | }, 2280 | "description": { 2281 | "en-US": "City pictured from the sky" 2282 | }, 2283 | "file": { 2284 | "en-US": { 2285 | "url": "//images.ctfassets.net/6yhac0bg4wbt/4NzwDSDlGECGIiokKomsyI/86275a4e41433e37db983026802e8d09/denys-nevozhai-100695.jpg", 2286 | "details": { 2287 | "size": 15736986, 2288 | "image": { 2289 | "width": 3992, 2290 | "height": 2992 2291 | } 2292 | }, 2293 | "fileName": "denys-nevozhai-100695.jpg", 2294 | "contentType": "image/jpeg" 2295 | } 2296 | } 2297 | } 2298 | } 2299 | ], 2300 | "locales": [ 2301 | { 2302 | "name": "U.S. English", 2303 | "code": "en-US", 2304 | "fallbackCode": null, 2305 | "default": true, 2306 | "contentManagementApi": true, 2307 | "contentDeliveryApi": true, 2308 | "optional": false, 2309 | "sys": { 2310 | "type": "Locale", 2311 | "id": "1ywdmntsiRUEpNK90awY8l", 2312 | "version": 2, 2313 | "space": { 2314 | "sys": { 2315 | "type": "Link", 2316 | "linkType": "Space", 2317 | "id": "6yhac0bg4wbt" 2318 | } 2319 | }, 2320 | "environment": { 2321 | "sys": { 2322 | "type": "Link", 2323 | "linkType": "Environment", 2324 | "id": "master" 2325 | } 2326 | }, 2327 | "createdBy": { 2328 | "sys": { 2329 | "type": "Link", 2330 | "linkType": "User", 2331 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2332 | } 2333 | }, 2334 | "createdAt": "2020-01-12T20:08:19Z", 2335 | "updatedBy": { 2336 | "sys": { 2337 | "type": "Link", 2338 | "linkType": "User", 2339 | "id": "1lkP8MOZgpIuq3eOIdgDou" 2340 | } 2341 | }, 2342 | "updatedAt": "2020-01-12T20:11:27Z" 2343 | } 2344 | } 2345 | ], 2346 | "webhooks": [], 2347 | "roles": [] 2348 | } 2349 | --------------------------------------------------------------------------------