├── styles └── globals.css ├── .eslintrc.json ├── .prettierrc ├── postcss.config.js ├── public └── favicon.ico ├── docs ├── copy-api-keys.png ├── generate-api-keys.png ├── generate-mgmt-token.png └── new-community-space.png ├── .env.example ├── netlify.toml ├── contentful ├── import-config.json ├── export-config.json ├── images.ctfassets.net │ └── hc8gnoolwanu │ │ └── o1G1j1B3fpZyVGa33M1zJ │ │ └── 098399e0b62a6e15d8d3cafc6f499bf1 │ │ └── fpo-sandwich.jpg ├── import.js └── export.json ├── renovate.json ├── src ├── app │ ├── layout.jsx │ ├── page.jsx │ └── [...slug] │ │ └── page.jsx ├── components │ ├── Button.jsx │ ├── Stats.jsx │ └── Hero.jsx └── utils │ └── content.js ├── next.config.js ├── .gitignore ├── package.json ├── stackbit.config.js └── README.md /styles/globals.css: -------------------------------------------------------------------------------- 1 | @import 'tailwindcss'; 2 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "singleQuote": true, 4 | "trailingComma": "all" 5 | } 6 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | '@tailwindcss/postcss': {}, 4 | }, 5 | } 6 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netlify-templates/nextjs-contentful-starter/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /docs/copy-api-keys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netlify-templates/nextjs-contentful-starter/HEAD/docs/copy-api-keys.png -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | CONTENTFUL_SPACE_ID= 2 | CONTENTFUL_MANAGEMENT_TOKEN= 3 | CONTENTFUL_DELIVERY_TOKEN= 4 | CONTENTFUL_PREVIEW_TOKEN= 5 | -------------------------------------------------------------------------------- /docs/generate-api-keys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netlify-templates/nextjs-contentful-starter/HEAD/docs/generate-api-keys.png -------------------------------------------------------------------------------- /docs/generate-mgmt-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netlify-templates/nextjs-contentful-starter/HEAD/docs/generate-mgmt-token.png -------------------------------------------------------------------------------- /docs/new-community-space.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netlify-templates/nextjs-contentful-starter/HEAD/docs/new-community-space.png -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [[plugins]] 2 | package = "@netlify/plugin-nextjs" 3 | 4 | [build] 5 | publish = ".next" 6 | command = "npm run build" -------------------------------------------------------------------------------- /contentful/import-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "contentFile": "contentful/export.json", 3 | "uploadAssets": true, 4 | "assetsDirectory": "contentful" 5 | } 6 | -------------------------------------------------------------------------------- /contentful/export-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "exportDir": "contentful", 3 | "contentFile": "export.json", 4 | "skipRoles": true, 5 | "downloadAssets": true 6 | } 7 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "local>netlify-templates/renovate-config" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /src/app/layout.jsx: -------------------------------------------------------------------------------- 1 | import '../../styles/globals.css'; 2 | 3 | export default async function RootLayout({ children }) { 4 | return ( 5 | 6 | 7 | {children} 8 | 9 | 10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | images: { 4 | remotePatterns: [ 5 | { 6 | protocol: 'https', 7 | hostname: 'images.ctfassets.net', 8 | }, 9 | ], 10 | }, 11 | }; 12 | 13 | module.exports = nextConfig; 14 | -------------------------------------------------------------------------------- /contentful/images.ctfassets.net/hc8gnoolwanu/o1G1j1B3fpZyVGa33M1zJ/098399e0b62a6e15d8d3cafc6f499bf1/fpo-sandwich.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netlify-templates/nextjs-contentful-starter/HEAD/contentful/images.ctfassets.net/hc8gnoolwanu/o1G1j1B3fpZyVGa33M1zJ/098399e0b62a6e15d8d3cafc6f499bf1/fpo-sandwich.jpg -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env* 30 | !.env.example 31 | 32 | # vercel 33 | .vercel 34 | 35 | .stackbit/cache 36 | # Local Netlify folder 37 | .netlify 38 | -------------------------------------------------------------------------------- /src/components/Button.jsx: -------------------------------------------------------------------------------- 1 | import Link from 'next/link'; 2 | 3 | const themeClassMap = { 4 | default: 'border-purple-700 bg-purple-700 text-white hover:bg-purple-500 hover:border-purple-500', 5 | outline: 'border-purple-700 bg-transparent text-purple-700 hover:text-purple-500 hover:border-purple-500', 6 | }; 7 | 8 | export const Button = (props) => { 9 | return ( 10 | 17 | {props.label} 18 | 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextjs-contentful-minimal-starter", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "import": "node ./contentful/import.js" 10 | }, 11 | "dependencies": { 12 | "markdown-to-jsx": "^7.4.7", 13 | "next": "^16.0.8", 14 | "react": "^19.2.1", 15 | "react-dom": "^19.2.1" 16 | }, 17 | "devDependencies": { 18 | "@stackbit/cms-contentful": "^1.0.0", 19 | "@stackbit/types": "^2.0.0", 20 | "@tailwindcss/postcss": "^4.0.0", 21 | "contentful-import": "^9.4.39", 22 | "dotenv": "^17.0.0", 23 | "eslint": "^9.0.0", 24 | "eslint-config-next": "^16.0.8", 25 | "postcss": "^8.5.1", 26 | "tailwindcss": "^4.0.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/app/page.jsx: -------------------------------------------------------------------------------- 1 | import { notFound } from 'next/navigation'; 2 | import { Hero } from '../components/Hero.jsx'; 3 | import { Stats } from '../components/Stats.jsx'; 4 | import { getPageFromSlug } from '../utils/content.js'; 5 | 6 | const componentMap = { 7 | hero: Hero, 8 | stats: Stats, 9 | }; 10 | 11 | export default async function ComposablePage() { 12 | try { 13 | const page = await getPageFromSlug("/"); 14 | 15 | if (!page) { 16 | return notFound(); 17 | } 18 | 19 | return ( 20 |
21 | {(page.sections || []).map((section, idx) => { 22 | const Component = componentMap[section.type]; 23 | return ; 24 | })} 25 |
26 | ); 27 | } catch (error) { 28 | console.error(error.message); 29 | return notFound(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/app/[...slug]/page.jsx: -------------------------------------------------------------------------------- 1 | import { notFound } from 'next/navigation'; 2 | import { Hero } from '../../components/Hero.jsx'; 3 | import { Stats } from '../../components/Stats.jsx'; 4 | import { getPageFromSlug } from '../../utils/content.js'; 5 | 6 | const componentMap = { 7 | hero: Hero, 8 | stats: Stats, 9 | }; 10 | 11 | export default async function ComposablePage({ params }) { 12 | const { slug } = params; 13 | 14 | const pageSlug = slug.join('/'); 15 | 16 | try { 17 | const page = await getPageFromSlug(`/${pageSlug}`); 18 | 19 | if (!page) { 20 | return notFound(); 21 | } 22 | 23 | return ( 24 |
25 | {(page.sections || []).map((section, idx) => { 26 | const Component = componentMap[section.type]; 27 | return ; 28 | })} 29 |
30 | ); 31 | } catch (error) { 32 | console.error(error.message); 33 | return notFound(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /contentful/import.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const path = require('path'); 4 | const contentfulImport = require('contentful-import'); 5 | const dotenv = require('dotenv'); 6 | 7 | dotenv.config(); 8 | 9 | const managementToken = process.env.CONTENTFUL_MANAGEMENT_TOKEN || process.argv[2]; 10 | const spaceId = process.env.CONTENTFUL_SPACE_ID || process.argv[3]; 11 | 12 | if (!managementToken || !spaceId) { 13 | console.error( 14 | 'Contentful management token or space ID were not provided.\n\nUsage:\n./export.js \n', 15 | ); 16 | process.exit(1); 17 | } 18 | 19 | const options = { 20 | contentFile: path.join(__dirname, 'export.json'), 21 | spaceId: spaceId, 22 | managementToken: managementToken, 23 | uploadAssets: true, 24 | assetsDirectory: __dirname, 25 | }; 26 | 27 | contentfulImport(options) 28 | .then(() => { 29 | console.log('Data imported successfully'); 30 | }) 31 | .catch((error) => { 32 | console.error('Error importing content:', error); 33 | }); 34 | -------------------------------------------------------------------------------- /stackbit.config.js: -------------------------------------------------------------------------------- 1 | import { ContentfulContentSource } from '@stackbit/cms-contentful'; 2 | 3 | const config = { 4 | stackbitVersion: '~0.6.0', 5 | ssgName: 'nextjs', 6 | nodeVersion: '18', 7 | contentSources: [ 8 | new ContentfulContentSource({ 9 | spaceId: process.env.CONTENTFUL_SPACE_ID, 10 | environment: process.env.CONTENTFUL_ENVIRONMENT || 'master', 11 | previewToken: process.env.CONTENTFUL_PREVIEW_TOKEN, 12 | accessToken: process.env.CONTENTFUL_MANAGEMENT_TOKEN, 13 | }), 14 | ], 15 | modelExtensions: [{ name: 'page', type: 'page', urlPath: '/{slug}' }], 16 | // Needed only for importing this repository via https://app.stackbit.com/import?mode=duplicate 17 | import: { 18 | type: 'contentful', 19 | contentFile: 'contentful/export.json', 20 | uploadAssets: true, 21 | assetsDirectory: 'contentful', 22 | spaceIdEnvVar: 'CONTENTFUL_SPACE_ID', 23 | deliveryTokenEnvVar: 'CONTENTFUL_DELIVERY_TOKEN', 24 | previewTokenEnvVar: 'CONTENTFUL_PREVIEW_TOKEN', 25 | accessTokenEnvVar: 'CONTENTFUL_MANAGEMENT_TOKEN', 26 | }, 27 | }; 28 | 29 | export default config; 30 | -------------------------------------------------------------------------------- /src/components/Stats.jsx: -------------------------------------------------------------------------------- 1 | import Markdown from 'markdown-to-jsx'; 2 | 3 | const themeClassMap = { 4 | primary: 'bg-purple-700 text-white', 5 | dark: 'bg-gray-800 text-white', 6 | }; 7 | 8 | export const Stats = (props) => { 9 | return ( 10 |
14 |
15 |
16 |

17 | {props.heading} 18 |

19 | {props.body && 20 | {props.body} 21 | } 22 |
23 |
24 | {(props.stats || []).map((stat, idx) => )} 25 |
26 |
27 |
28 | ); 29 | }; 30 | 31 | const StatItem = (props) => { 32 | return ( 33 |
34 |
35 | {props.value} 36 |
37 |
{props.label}
38 |
39 | ); 40 | }; 41 | -------------------------------------------------------------------------------- /src/components/Hero.jsx: -------------------------------------------------------------------------------- 1 | import Markdown from 'markdown-to-jsx'; 2 | import Image from 'next/image'; 3 | import { Button } from './Button.jsx'; 4 | 5 | const themeClassMap = { 6 | imgLeft: 'md:flex-row-reverse', 7 | imgRight: 'md:flex-row', 8 | }; 9 | 10 | export const Hero = (props) => { 11 | return ( 12 |
13 |
14 |
15 |

16 | {props.heading} 17 |

18 | {props.body && ( 19 | 20 | {props.body} 21 | 22 | )} 23 | {props.button &&
25 |
26 | {props.image && ( 27 | {props.image.alt} 35 | )} 36 |
37 |
38 |
39 | ); 40 | }; 41 | -------------------------------------------------------------------------------- /src/utils/content.js: -------------------------------------------------------------------------------- 1 | import { createClient } from 'contentful'; 2 | 3 | const PAGE_CONTENT_TYPE_ID = 'page'; 4 | const IS_DEV = process.env.NODE_ENV === 'development'; 5 | 6 | async function getEntries(content_type, queryParams) { 7 | const client = createClient({ 8 | accessToken: IS_DEV ? process.env.CONTENTFUL_PREVIEW_TOKEN : process.env.CONTENTFUL_DELIVERY_TOKEN, 9 | space: process.env.CONTENTFUL_SPACE_ID, 10 | host: IS_DEV ? 'preview.contentful.com' : 'cdn.contentful.com', 11 | }); 12 | 13 | const entries = await client.getEntries({ content_type, ...queryParams, include: 10 }); 14 | return entries; 15 | } 16 | 17 | export async function getPagePaths() { 18 | const { items } = await getEntries(PAGE_CONTENT_TYPE_ID); 19 | return items.map((page) => { 20 | const slug = page.fields.slug; 21 | return slug.startsWith('/') ? slug : `/${slug}`; 22 | }); 23 | } 24 | 25 | export async function getPageFromSlug(slug) { 26 | const { items } = await getEntries(PAGE_CONTENT_TYPE_ID, { 'fields.slug': slug }); 27 | let page = (items ?? [])[0]; 28 | if (!page && slug !== '/' && slug.startsWith('/')) { 29 | const { items } = await getEntries(PAGE_CONTENT_TYPE_ID, { 'fields.slug': slug.slice(1) }); 30 | page = (items ?? [])[0]; 31 | } 32 | if (!page) throw new Error(`Page not found for slug: ${slug}`); 33 | return mapEntry(page); 34 | } 35 | 36 | function mapEntry(entry) { 37 | const id = entry.sys?.id; 38 | const type = entry.sys?.contentType?.sys?.id || entry.sys?.type; 39 | 40 | if (entry.sys?.type === 'Asset') { 41 | return { 42 | id, 43 | type, 44 | src: `https:${entry.fields.file.url}`, 45 | alt: entry.fields.title, 46 | }; 47 | } 48 | 49 | return { 50 | id, 51 | type, 52 | ...Object.fromEntries(Object.entries(entry.fields).map(([key, value]) => [key, parseField(value)])), 53 | }; 54 | } 55 | 56 | function parseField(value) { 57 | if (typeof value === 'object' && value.sys) return mapEntry(value); 58 | if (Array.isArray(value)) return value.map(mapEntry); 59 | return value; 60 | } 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Netlify Next.js + Contentful Minimal Starter 2 | 3 | ![Screenshot](https://assets.stackbit.com/docs/tutorial-shared-thumb.png) 4 | 5 | **⚡ View demo:** [nextjs-contentful-starter.netlify.app](https://nextjs-contentful-starter.netlify.app/) 6 | 7 | ## Prerequisites 8 | 9 | Before you begin, please make sure you have the following: 10 | 11 | - [Netlify account](https://www.netlify.com/) 12 | - [Contentful account](https://www.contentful.com/) 13 | - GitHub, GitLab or Bitbucket account 14 | - Node v18+ or later 15 | - (optional) [nvm](https://github.com/nvm-sh/nvm) for Node version management. 16 | 17 | ## Getting Started 18 | 19 | ### Clone this repository 20 | 21 | Fork and clone your repository, then run `npm install` in its root directory. 22 | 23 | ### Create Contentful Space 24 | 25 | After signing into Contentful, create a new space. 26 | 27 | ### Generate Management Token 28 | 29 | If you don't already have a management token (or _personal access token_), generate one. To do so, go into your new empty space, then: 30 | 31 | 1. Click _Settings_ 32 | 1. Choose _API Keys_ 33 | 1. Select the _Content management tokens_ tab 34 | 1. Click the button to generate a new token 35 | 36 | ![Generate content management token](./docs/generate-mgmt-token.png) 37 | 38 | ### Generate Preview & Delivery API Keys 39 | 40 | From the same place you generated the management token, you can now generate API access keys. 41 | 42 | 1. Select the *content delivery / preview tokens* tab 43 | 1. Choose *Add API key* 44 | 45 | ### Set Environment Variables 46 | 47 | In your project, duplicate `.env.example` to `.env`. 48 | 49 | Fill in the values in the file based on the keys you've created. 50 | 51 | Note: the Contentful space ID can be viewed and copied via *Settings->General Settings* in Contentful. 52 | 53 | ### Import Content 54 | 55 | Import the provided content models & content into Contentful by running the `import.js` script: 56 | 57 | npm run import 58 | 59 | If the import fails to run, make sure that you've run `npm install` and that all keys in your `.env` file are set correctly. 60 | 61 | ### Run the Website 62 | 63 | Run the Next.js development server: 64 | 65 | npm run dev 66 | 67 | Visit [localhost:3000](http://localhost:3000) and you should see the example content you imported into your new Contentful space. 68 | 69 | ### Run Netlify Visual Editor in Local Development Mode 70 | 71 | Keep the Next.js development server running, and open a new command-line window in the same directory. 72 | 73 | Install Stackbit's CLI tools (once): 74 | 75 | npm i -g @stackbit/cli@latest 76 | 77 | Run the CLI: 78 | 79 | stackbit dev 80 | 81 | Click the displayed link to [localhost:8090/_stackbit](http://localhost:8090/_stackbit) and the visual editor will open. 82 | 83 | ### Create a Cloud-Based Netlify Project 84 | 85 | To deploy a cloud-based Netlify project your need to connected your repository to Netlify: 86 | 87 | 1. If you haven't created your GitHub project repository, create it and push your code to GitHub 88 | 2. Open the [app.netlify.com](https://app.netlify.com/), and choose "Import from Git" in the "Import an existing project" section 89 | 3. In the "Configure site and deploy" step you will see the "Visual editor" section. To make it work, you will need to install "Netlify Visual Editor GitHub App" in your GitHub account. 90 | 4. Deploy your project 91 | 92 | ## Next Steps 93 | 94 | Here are a few suggestions on what to do next if you're new to Netlify visual editor: 95 | 96 | - Learn [how Netlify visual editor works](https://docs.netlify.com/visual-editor/overview/) 97 | - Check [Netlify visual editor reference documentation](https://visual-editor-reference.netlify.com/) 98 | 99 | ## Support 100 | 101 | If you get stuck along the way, get help in our [support forums](https://answers.netlify.com/). 102 | -------------------------------------------------------------------------------- /contentful/export.json: -------------------------------------------------------------------------------- 1 | { 2 | "contentTypes": [ 3 | { 4 | "sys": { 5 | "space": { 6 | "sys": { 7 | "type": "Link", 8 | "linkType": "Space", 9 | "id": "hc8gnoolwanu" 10 | } 11 | }, 12 | "id": "hero", 13 | "type": "ContentType", 14 | "createdAt": "2023-12-07T10:53:26.106Z", 15 | "updatedAt": "2023-12-07T10:56:51.175Z", 16 | "environment": { 17 | "sys": { 18 | "id": "master", 19 | "type": "Link", 20 | "linkType": "Environment" 21 | } 22 | }, 23 | "publishedVersion": 3, 24 | "publishedAt": "2023-12-07T10:56:51.175Z", 25 | "firstPublishedAt": "2023-12-07T10:53:27.258Z", 26 | "createdBy": { 27 | "sys": { 28 | "type": "Link", 29 | "linkType": "User", 30 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 31 | } 32 | }, 33 | "updatedBy": { 34 | "sys": { 35 | "type": "Link", 36 | "linkType": "User", 37 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 38 | } 39 | }, 40 | "publishedCounter": 2, 41 | "version": 4, 42 | "publishedBy": { 43 | "sys": { 44 | "type": "Link", 45 | "linkType": "User", 46 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 47 | } 48 | } 49 | }, 50 | "displayField": "heading", 51 | "name": "Hero", 52 | "description": "", 53 | "fields": [ 54 | { 55 | "id": "heading", 56 | "name": "Heading", 57 | "type": "Symbol", 58 | "localized": false, 59 | "required": true, 60 | "validations": [ 61 | ], 62 | "disabled": false, 63 | "omitted": false 64 | }, 65 | { 66 | "id": "body", 67 | "name": "Body", 68 | "type": "Text", 69 | "localized": false, 70 | "required": false, 71 | "validations": [ 72 | ], 73 | "disabled": false, 74 | "omitted": false 75 | }, 76 | { 77 | "id": "image", 78 | "name": "Image", 79 | "type": "Link", 80 | "localized": false, 81 | "required": true, 82 | "validations": [ 83 | ], 84 | "disabled": false, 85 | "omitted": false, 86 | "linkType": "Asset" 87 | }, 88 | { 89 | "id": "button", 90 | "name": "Button", 91 | "type": "Link", 92 | "localized": false, 93 | "required": true, 94 | "validations": [ 95 | { 96 | "linkContentType": [ 97 | "button" 98 | ] 99 | } 100 | ], 101 | "disabled": false, 102 | "omitted": false, 103 | "linkType": "Entry" 104 | }, 105 | { 106 | "id": "theme", 107 | "name": "Theme", 108 | "type": "Symbol", 109 | "localized": false, 110 | "required": true, 111 | "validations": [ 112 | { 113 | "in": [ 114 | "imgLeft", 115 | "imgRight" 116 | ] 117 | } 118 | ], 119 | "disabled": false, 120 | "omitted": false 121 | } 122 | ] 123 | }, 124 | { 125 | "sys": { 126 | "space": { 127 | "sys": { 128 | "type": "Link", 129 | "linkType": "Space", 130 | "id": "hc8gnoolwanu" 131 | } 132 | }, 133 | "id": "button", 134 | "type": "ContentType", 135 | "createdAt": "2023-12-07T10:53:26.134Z", 136 | "updatedAt": "2023-12-07T10:53:26.768Z", 137 | "environment": { 138 | "sys": { 139 | "id": "master", 140 | "type": "Link", 141 | "linkType": "Environment" 142 | } 143 | }, 144 | "publishedVersion": 1, 145 | "publishedAt": "2023-12-07T10:53:26.768Z", 146 | "firstPublishedAt": "2023-12-07T10:53:26.768Z", 147 | "createdBy": { 148 | "sys": { 149 | "type": "Link", 150 | "linkType": "User", 151 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 152 | } 153 | }, 154 | "updatedBy": { 155 | "sys": { 156 | "type": "Link", 157 | "linkType": "User", 158 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 159 | } 160 | }, 161 | "publishedCounter": 1, 162 | "version": 2, 163 | "publishedBy": { 164 | "sys": { 165 | "type": "Link", 166 | "linkType": "User", 167 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 168 | } 169 | } 170 | }, 171 | "displayField": "label", 172 | "name": "Button", 173 | "description": "", 174 | "fields": [ 175 | { 176 | "id": "label", 177 | "name": "Label", 178 | "type": "Symbol", 179 | "localized": false, 180 | "required": true, 181 | "validations": [ 182 | ], 183 | "disabled": false, 184 | "omitted": false 185 | }, 186 | { 187 | "id": "url", 188 | "name": "URL", 189 | "type": "Symbol", 190 | "localized": false, 191 | "required": true, 192 | "validations": [ 193 | ], 194 | "disabled": false, 195 | "omitted": false 196 | }, 197 | { 198 | "id": "theme", 199 | "name": "Theme", 200 | "type": "Symbol", 201 | "localized": false, 202 | "required": true, 203 | "validations": [ 204 | { 205 | "in": [ 206 | "default", 207 | "outline" 208 | ] 209 | } 210 | ], 211 | "disabled": false, 212 | "omitted": false 213 | } 214 | ] 215 | }, 216 | { 217 | "sys": { 218 | "space": { 219 | "sys": { 220 | "type": "Link", 221 | "linkType": "Space", 222 | "id": "hc8gnoolwanu" 223 | } 224 | }, 225 | "id": "stats", 226 | "type": "ContentType", 227 | "createdAt": "2023-12-07T10:53:26.173Z", 228 | "updatedAt": "2023-12-07T10:57:05.131Z", 229 | "environment": { 230 | "sys": { 231 | "id": "master", 232 | "type": "Link", 233 | "linkType": "Environment" 234 | } 235 | }, 236 | "publishedVersion": 3, 237 | "publishedAt": "2023-12-07T10:57:05.131Z", 238 | "firstPublishedAt": "2023-12-07T10:53:27.829Z", 239 | "createdBy": { 240 | "sys": { 241 | "type": "Link", 242 | "linkType": "User", 243 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 244 | } 245 | }, 246 | "updatedBy": { 247 | "sys": { 248 | "type": "Link", 249 | "linkType": "User", 250 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 251 | } 252 | }, 253 | "publishedCounter": 2, 254 | "version": 4, 255 | "publishedBy": { 256 | "sys": { 257 | "type": "Link", 258 | "linkType": "User", 259 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 260 | } 261 | } 262 | }, 263 | "displayField": "heading", 264 | "name": "Stats", 265 | "description": "", 266 | "fields": [ 267 | { 268 | "id": "heading", 269 | "name": "Heading", 270 | "type": "Symbol", 271 | "localized": false, 272 | "required": true, 273 | "validations": [ 274 | ], 275 | "disabled": false, 276 | "omitted": false 277 | }, 278 | { 279 | "id": "body", 280 | "name": "Body", 281 | "type": "Text", 282 | "localized": false, 283 | "required": false, 284 | "validations": [ 285 | ], 286 | "disabled": false, 287 | "omitted": false 288 | }, 289 | { 290 | "id": "theme", 291 | "name": "Theme", 292 | "type": "Symbol", 293 | "localized": false, 294 | "required": true, 295 | "validations": [ 296 | { 297 | "in": [ 298 | "primary", 299 | "dark" 300 | ] 301 | } 302 | ], 303 | "disabled": false, 304 | "omitted": false 305 | }, 306 | { 307 | "id": "stats", 308 | "name": "Stats", 309 | "type": "Array", 310 | "localized": false, 311 | "required": true, 312 | "validations": [ 313 | ], 314 | "disabled": false, 315 | "omitted": false, 316 | "items": { 317 | "type": "Link", 318 | "validations": [ 319 | { 320 | "linkContentType": [ 321 | "statItem" 322 | ] 323 | } 324 | ], 325 | "linkType": "Entry" 326 | } 327 | } 328 | ] 329 | }, 330 | { 331 | "sys": { 332 | "space": { 333 | "sys": { 334 | "type": "Link", 335 | "linkType": "Space", 336 | "id": "hc8gnoolwanu" 337 | } 338 | }, 339 | "id": "statItem", 340 | "type": "ContentType", 341 | "createdAt": "2023-12-07T10:53:26.209Z", 342 | "updatedAt": "2023-12-07T10:53:27.613Z", 343 | "environment": { 344 | "sys": { 345 | "id": "master", 346 | "type": "Link", 347 | "linkType": "Environment" 348 | } 349 | }, 350 | "publishedVersion": 1, 351 | "publishedAt": "2023-12-07T10:53:27.613Z", 352 | "firstPublishedAt": "2023-12-07T10:53:27.613Z", 353 | "createdBy": { 354 | "sys": { 355 | "type": "Link", 356 | "linkType": "User", 357 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 358 | } 359 | }, 360 | "updatedBy": { 361 | "sys": { 362 | "type": "Link", 363 | "linkType": "User", 364 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 365 | } 366 | }, 367 | "publishedCounter": 1, 368 | "version": 2, 369 | "publishedBy": { 370 | "sys": { 371 | "type": "Link", 372 | "linkType": "User", 373 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 374 | } 375 | } 376 | }, 377 | "displayField": "label", 378 | "name": "StatItem", 379 | "description": "", 380 | "fields": [ 381 | { 382 | "id": "label", 383 | "name": "Label", 384 | "type": "Symbol", 385 | "localized": false, 386 | "required": true, 387 | "validations": [ 388 | ], 389 | "disabled": false, 390 | "omitted": false 391 | }, 392 | { 393 | "id": "value", 394 | "name": "Value", 395 | "type": "Symbol", 396 | "localized": false, 397 | "required": true, 398 | "validations": [ 399 | ], 400 | "disabled": false, 401 | "omitted": false 402 | } 403 | ] 404 | }, 405 | { 406 | "sys": { 407 | "space": { 408 | "sys": { 409 | "type": "Link", 410 | "linkType": "Space", 411 | "id": "hc8gnoolwanu" 412 | } 413 | }, 414 | "id": "page", 415 | "type": "ContentType", 416 | "createdAt": "2023-12-07T10:53:26.220Z", 417 | "updatedAt": "2023-12-07T10:53:28.116Z", 418 | "environment": { 419 | "sys": { 420 | "id": "master", 421 | "type": "Link", 422 | "linkType": "Environment" 423 | } 424 | }, 425 | "publishedVersion": 1, 426 | "publishedAt": "2023-12-07T10:53:28.116Z", 427 | "firstPublishedAt": "2023-12-07T10:53:28.116Z", 428 | "createdBy": { 429 | "sys": { 430 | "type": "Link", 431 | "linkType": "User", 432 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 433 | } 434 | }, 435 | "updatedBy": { 436 | "sys": { 437 | "type": "Link", 438 | "linkType": "User", 439 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 440 | } 441 | }, 442 | "publishedCounter": 1, 443 | "version": 2, 444 | "publishedBy": { 445 | "sys": { 446 | "type": "Link", 447 | "linkType": "User", 448 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 449 | } 450 | } 451 | }, 452 | "displayField": "title", 453 | "name": "Page", 454 | "description": "", 455 | "fields": [ 456 | { 457 | "id": "title", 458 | "name": "Title", 459 | "type": "Symbol", 460 | "localized": false, 461 | "required": true, 462 | "validations": [ 463 | ], 464 | "disabled": false, 465 | "omitted": false 466 | }, 467 | { 468 | "id": "slug", 469 | "name": "Slug", 470 | "type": "Symbol", 471 | "localized": false, 472 | "required": true, 473 | "validations": [ 474 | { 475 | "unique": true 476 | } 477 | ], 478 | "disabled": false, 479 | "omitted": false 480 | }, 481 | { 482 | "id": "sections", 483 | "name": "Sections", 484 | "type": "Array", 485 | "localized": false, 486 | "required": true, 487 | "validations": [ 488 | ], 489 | "disabled": false, 490 | "omitted": false, 491 | "items": { 492 | "type": "Link", 493 | "validations": [ 494 | { 495 | "linkContentType": [ 496 | "hero", 497 | "stats" 498 | ] 499 | } 500 | ], 501 | "linkType": "Entry" 502 | } 503 | } 504 | ] 505 | } 506 | ], 507 | "tags": [ 508 | ], 509 | "editorInterfaces": [ 510 | { 511 | "sys": { 512 | "id": "default", 513 | "type": "EditorInterface", 514 | "space": { 515 | "sys": { 516 | "id": "hc8gnoolwanu", 517 | "type": "Link", 518 | "linkType": "Space" 519 | } 520 | }, 521 | "version": 4, 522 | "createdAt": "2023-12-07T10:53:27.436Z", 523 | "createdBy": { 524 | "sys": { 525 | "id": "1JaKkSjxX8SGAGTUKV3JYB", 526 | "type": "Link", 527 | "linkType": "User" 528 | } 529 | }, 530 | "updatedAt": "2023-12-07T10:56:51.931Z", 531 | "updatedBy": { 532 | "sys": { 533 | "id": "1JaKkSjxX8SGAGTUKV3JYB", 534 | "type": "Link", 535 | "linkType": "User" 536 | } 537 | }, 538 | "contentType": { 539 | "sys": { 540 | "id": "hero", 541 | "type": "Link", 542 | "linkType": "ContentType" 543 | } 544 | }, 545 | "environment": { 546 | "sys": { 547 | "id": "master", 548 | "type": "Link", 549 | "linkType": "Environment" 550 | } 551 | } 552 | }, 553 | "controls": [ 554 | { 555 | "fieldId": "heading", 556 | "widgetId": "singleLine", 557 | "widgetNamespace": "builtin" 558 | }, 559 | { 560 | "fieldId": "body", 561 | "widgetId": "markdown", 562 | "widgetNamespace": "builtin" 563 | }, 564 | { 565 | "fieldId": "image", 566 | "widgetId": "assetLinkEditor", 567 | "widgetNamespace": "builtin" 568 | }, 569 | { 570 | "fieldId": "button", 571 | "widgetId": "entryLinkEditor", 572 | "widgetNamespace": "builtin" 573 | }, 574 | { 575 | "fieldId": "theme", 576 | "widgetId": "dropdown", 577 | "widgetNamespace": "builtin" 578 | } 579 | ] 580 | }, 581 | { 582 | "sys": { 583 | "id": "default", 584 | "type": "EditorInterface", 585 | "space": { 586 | "sys": { 587 | "id": "hc8gnoolwanu", 588 | "type": "Link", 589 | "linkType": "Space" 590 | } 591 | }, 592 | "version": 2, 593 | "createdAt": "2023-12-07T10:53:26.952Z", 594 | "createdBy": { 595 | "sys": { 596 | "id": "1JaKkSjxX8SGAGTUKV3JYB", 597 | "type": "Link", 598 | "linkType": "User" 599 | } 600 | }, 601 | "updatedAt": "2023-12-07T10:53:29.090Z", 602 | "updatedBy": { 603 | "sys": { 604 | "id": "1JaKkSjxX8SGAGTUKV3JYB", 605 | "type": "Link", 606 | "linkType": "User" 607 | } 608 | }, 609 | "contentType": { 610 | "sys": { 611 | "id": "button", 612 | "type": "Link", 613 | "linkType": "ContentType" 614 | } 615 | }, 616 | "environment": { 617 | "sys": { 618 | "id": "master", 619 | "type": "Link", 620 | "linkType": "Environment" 621 | } 622 | } 623 | }, 624 | "controls": [ 625 | { 626 | "fieldId": "label", 627 | "widgetId": "singleLine", 628 | "widgetNamespace": "builtin" 629 | }, 630 | { 631 | "fieldId": "url", 632 | "widgetId": "singleLine", 633 | "widgetNamespace": "builtin" 634 | }, 635 | { 636 | "fieldId": "theme", 637 | "widgetId": "dropdown", 638 | "widgetNamespace": "builtin" 639 | } 640 | ] 641 | }, 642 | { 643 | "sys": { 644 | "id": "default", 645 | "type": "EditorInterface", 646 | "space": { 647 | "sys": { 648 | "id": "hc8gnoolwanu", 649 | "type": "Link", 650 | "linkType": "Space" 651 | } 652 | }, 653 | "version": 4, 654 | "createdAt": "2023-12-07T10:53:27.993Z", 655 | "createdBy": { 656 | "sys": { 657 | "id": "1JaKkSjxX8SGAGTUKV3JYB", 658 | "type": "Link", 659 | "linkType": "User" 660 | } 661 | }, 662 | "updatedAt": "2023-12-07T10:57:05.851Z", 663 | "updatedBy": { 664 | "sys": { 665 | "id": "1JaKkSjxX8SGAGTUKV3JYB", 666 | "type": "Link", 667 | "linkType": "User" 668 | } 669 | }, 670 | "contentType": { 671 | "sys": { 672 | "id": "stats", 673 | "type": "Link", 674 | "linkType": "ContentType" 675 | } 676 | }, 677 | "environment": { 678 | "sys": { 679 | "id": "master", 680 | "type": "Link", 681 | "linkType": "Environment" 682 | } 683 | } 684 | }, 685 | "controls": [ 686 | { 687 | "fieldId": "heading", 688 | "widgetId": "singleLine", 689 | "widgetNamespace": "builtin" 690 | }, 691 | { 692 | "fieldId": "body", 693 | "widgetId": "markdown", 694 | "widgetNamespace": "builtin" 695 | }, 696 | { 697 | "fieldId": "theme", 698 | "widgetId": "dropdown", 699 | "widgetNamespace": "builtin" 700 | }, 701 | { 702 | "fieldId": "stats", 703 | "widgetId": "entryLinksEditor", 704 | "widgetNamespace": "builtin" 705 | } 706 | ] 707 | }, 708 | { 709 | "sys": { 710 | "id": "default", 711 | "type": "EditorInterface", 712 | "space": { 713 | "sys": { 714 | "id": "hc8gnoolwanu", 715 | "type": "Link", 716 | "linkType": "Space" 717 | } 718 | }, 719 | "version": 2, 720 | "createdAt": "2023-12-07T10:53:27.699Z", 721 | "createdBy": { 722 | "sys": { 723 | "id": "1JaKkSjxX8SGAGTUKV3JYB", 724 | "type": "Link", 725 | "linkType": "User" 726 | } 727 | }, 728 | "updatedAt": "2023-12-07T10:53:29.090Z", 729 | "updatedBy": { 730 | "sys": { 731 | "id": "1JaKkSjxX8SGAGTUKV3JYB", 732 | "type": "Link", 733 | "linkType": "User" 734 | } 735 | }, 736 | "contentType": { 737 | "sys": { 738 | "id": "statItem", 739 | "type": "Link", 740 | "linkType": "ContentType" 741 | } 742 | }, 743 | "environment": { 744 | "sys": { 745 | "id": "master", 746 | "type": "Link", 747 | "linkType": "Environment" 748 | } 749 | } 750 | }, 751 | "controls": [ 752 | { 753 | "fieldId": "label", 754 | "widgetId": "singleLine", 755 | "widgetNamespace": "builtin" 756 | }, 757 | { 758 | "fieldId": "value", 759 | "widgetId": "singleLine", 760 | "widgetNamespace": "builtin" 761 | } 762 | ] 763 | }, 764 | { 765 | "sys": { 766 | "id": "default", 767 | "type": "EditorInterface", 768 | "space": { 769 | "sys": { 770 | "id": "hc8gnoolwanu", 771 | "type": "Link", 772 | "linkType": "Space" 773 | } 774 | }, 775 | "version": 2, 776 | "createdAt": "2023-12-07T10:53:28.241Z", 777 | "createdBy": { 778 | "sys": { 779 | "id": "1JaKkSjxX8SGAGTUKV3JYB", 780 | "type": "Link", 781 | "linkType": "User" 782 | } 783 | }, 784 | "updatedAt": "2023-12-07T10:53:29.105Z", 785 | "updatedBy": { 786 | "sys": { 787 | "id": "1JaKkSjxX8SGAGTUKV3JYB", 788 | "type": "Link", 789 | "linkType": "User" 790 | } 791 | }, 792 | "contentType": { 793 | "sys": { 794 | "id": "page", 795 | "type": "Link", 796 | "linkType": "ContentType" 797 | } 798 | }, 799 | "environment": { 800 | "sys": { 801 | "id": "master", 802 | "type": "Link", 803 | "linkType": "Environment" 804 | } 805 | } 806 | }, 807 | "controls": [ 808 | { 809 | "fieldId": "title", 810 | "widgetId": "singleLine", 811 | "widgetNamespace": "builtin" 812 | }, 813 | { 814 | "fieldId": "slug", 815 | "widgetId": "slugEditor", 816 | "widgetNamespace": "builtin" 817 | }, 818 | { 819 | "fieldId": "sections", 820 | "widgetId": "entryLinksEditor", 821 | "widgetNamespace": "builtin" 822 | } 823 | ] 824 | } 825 | ], 826 | "entries": [ 827 | { 828 | "metadata": { 829 | "tags": [ 830 | ] 831 | }, 832 | "sys": { 833 | "space": { 834 | "sys": { 835 | "type": "Link", 836 | "linkType": "Space", 837 | "id": "hc8gnoolwanu" 838 | } 839 | }, 840 | "id": "4kqY1iB0OrQxrIfptA3THs", 841 | "type": "Entry", 842 | "createdAt": "2023-12-07T10:53:34.089Z", 843 | "updatedAt": "2023-12-07T10:53:35.527Z", 844 | "environment": { 845 | "sys": { 846 | "id": "master", 847 | "type": "Link", 848 | "linkType": "Environment" 849 | } 850 | }, 851 | "publishedVersion": 1, 852 | "publishedAt": "2023-12-07T10:53:35.527Z", 853 | "firstPublishedAt": "2023-12-07T10:53:35.527Z", 854 | "createdBy": { 855 | "sys": { 856 | "type": "Link", 857 | "linkType": "User", 858 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 859 | } 860 | }, 861 | "updatedBy": { 862 | "sys": { 863 | "type": "Link", 864 | "linkType": "User", 865 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 866 | } 867 | }, 868 | "publishedCounter": 1, 869 | "version": 2, 870 | "publishedBy": { 871 | "sys": { 872 | "type": "Link", 873 | "linkType": "User", 874 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 875 | } 876 | }, 877 | "automationTags": [ 878 | ], 879 | "contentType": { 880 | "sys": { 881 | "type": "Link", 882 | "linkType": "ContentType", 883 | "id": "statItem" 884 | } 885 | } 886 | }, 887 | "fields": { 888 | "label": { 889 | "en-US": "Graduation rate" 890 | }, 891 | "value": { 892 | "en-US": "100%" 893 | } 894 | } 895 | }, 896 | { 897 | "metadata": { 898 | "tags": [ 899 | ] 900 | }, 901 | "sys": { 902 | "space": { 903 | "sys": { 904 | "type": "Link", 905 | "linkType": "Space", 906 | "id": "hc8gnoolwanu" 907 | } 908 | }, 909 | "id": "1waD7wlBFDmDTKcI18NXO0", 910 | "type": "Entry", 911 | "createdAt": "2023-12-07T10:53:34.109Z", 912 | "updatedAt": "2023-12-07T10:53:36.960Z", 913 | "environment": { 914 | "sys": { 915 | "id": "master", 916 | "type": "Link", 917 | "linkType": "Environment" 918 | } 919 | }, 920 | "publishedVersion": 1, 921 | "publishedAt": "2023-12-07T10:53:36.960Z", 922 | "firstPublishedAt": "2023-12-07T10:53:36.960Z", 923 | "createdBy": { 924 | "sys": { 925 | "type": "Link", 926 | "linkType": "User", 927 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 928 | } 929 | }, 930 | "updatedBy": { 931 | "sys": { 932 | "type": "Link", 933 | "linkType": "User", 934 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 935 | } 936 | }, 937 | "publishedCounter": 1, 938 | "version": 2, 939 | "publishedBy": { 940 | "sys": { 941 | "type": "Link", 942 | "linkType": "User", 943 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 944 | } 945 | }, 946 | "automationTags": [ 947 | ], 948 | "contentType": { 949 | "sys": { 950 | "type": "Link", 951 | "linkType": "ContentType", 952 | "id": "hero" 953 | } 954 | } 955 | }, 956 | "fields": { 957 | "heading": { 958 | "en-US": "Can you make the perfect sandwich?" 959 | }, 960 | "body": { 961 | "en-US": "HandSandwich™️ is Central Southwestern Ohio's most highly attended sandwich-making class. Don't delay your ability to craft the perfect sandwich." 962 | }, 963 | "image": { 964 | "en-US": { 965 | "sys": { 966 | "type": "Link", 967 | "linkType": "Asset", 968 | "id": "o1G1j1B3fpZyVGa33M1zJ" 969 | } 970 | } 971 | }, 972 | "button": { 973 | "en-US": { 974 | "sys": { 975 | "type": "Link", 976 | "linkType": "Entry", 977 | "id": "36U7omnF7aFEHjVKwEhJI7" 978 | } 979 | } 980 | }, 981 | "theme": { 982 | "en-US": "imgLeft" 983 | } 984 | } 985 | }, 986 | { 987 | "metadata": { 988 | "tags": [ 989 | ] 990 | }, 991 | "sys": { 992 | "space": { 993 | "sys": { 994 | "type": "Link", 995 | "linkType": "Space", 996 | "id": "hc8gnoolwanu" 997 | } 998 | }, 999 | "id": "55B39LpWGFDQvt4kYYif6g", 1000 | "type": "Entry", 1001 | "createdAt": "2023-12-07T10:53:34.137Z", 1002 | "updatedAt": "2023-12-07T10:53:36.580Z", 1003 | "environment": { 1004 | "sys": { 1005 | "id": "master", 1006 | "type": "Link", 1007 | "linkType": "Environment" 1008 | } 1009 | }, 1010 | "publishedVersion": 1, 1011 | "publishedAt": "2023-12-07T10:53:36.580Z", 1012 | "firstPublishedAt": "2023-12-07T10:53:36.580Z", 1013 | "createdBy": { 1014 | "sys": { 1015 | "type": "Link", 1016 | "linkType": "User", 1017 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1018 | } 1019 | }, 1020 | "updatedBy": { 1021 | "sys": { 1022 | "type": "Link", 1023 | "linkType": "User", 1024 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1025 | } 1026 | }, 1027 | "publishedCounter": 1, 1028 | "version": 2, 1029 | "publishedBy": { 1030 | "sys": { 1031 | "type": "Link", 1032 | "linkType": "User", 1033 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1034 | } 1035 | }, 1036 | "automationTags": [ 1037 | ], 1038 | "contentType": { 1039 | "sys": { 1040 | "type": "Link", 1041 | "linkType": "ContentType", 1042 | "id": "stats" 1043 | } 1044 | } 1045 | }, 1046 | "fields": { 1047 | "heading": { 1048 | "en-US": "Don't take our word for it" 1049 | }, 1050 | "body": { 1051 | "en-US": "Because we definitely didn't make up these numbers." 1052 | }, 1053 | "theme": { 1054 | "en-US": "dark" 1055 | }, 1056 | "stats": { 1057 | "en-US": [ 1058 | { 1059 | "sys": { 1060 | "type": "Link", 1061 | "linkType": "Entry", 1062 | "id": "4kqY1iB0OrQxrIfptA3THs" 1063 | } 1064 | }, 1065 | { 1066 | "sys": { 1067 | "type": "Link", 1068 | "linkType": "Entry", 1069 | "id": "3LwBRMadcjbZOr9AHo2KYM" 1070 | } 1071 | }, 1072 | { 1073 | "sys": { 1074 | "type": "Link", 1075 | "linkType": "Entry", 1076 | "id": "tnUnQwb0YfqbfdVAtCGSE" 1077 | } 1078 | } 1079 | ] 1080 | } 1081 | } 1082 | }, 1083 | { 1084 | "metadata": { 1085 | "tags": [ 1086 | ] 1087 | }, 1088 | "sys": { 1089 | "space": { 1090 | "sys": { 1091 | "type": "Link", 1092 | "linkType": "Space", 1093 | "id": "hc8gnoolwanu" 1094 | } 1095 | }, 1096 | "id": "tnUnQwb0YfqbfdVAtCGSE", 1097 | "type": "Entry", 1098 | "createdAt": "2023-12-07T10:53:34.150Z", 1099 | "updatedAt": "2023-12-07T10:53:36.135Z", 1100 | "environment": { 1101 | "sys": { 1102 | "id": "master", 1103 | "type": "Link", 1104 | "linkType": "Environment" 1105 | } 1106 | }, 1107 | "publishedVersion": 1, 1108 | "publishedAt": "2023-12-07T10:53:36.135Z", 1109 | "firstPublishedAt": "2023-12-07T10:53:36.135Z", 1110 | "createdBy": { 1111 | "sys": { 1112 | "type": "Link", 1113 | "linkType": "User", 1114 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1115 | } 1116 | }, 1117 | "updatedBy": { 1118 | "sys": { 1119 | "type": "Link", 1120 | "linkType": "User", 1121 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1122 | } 1123 | }, 1124 | "publishedCounter": 1, 1125 | "version": 2, 1126 | "publishedBy": { 1127 | "sys": { 1128 | "type": "Link", 1129 | "linkType": "User", 1130 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1131 | } 1132 | }, 1133 | "automationTags": [ 1134 | ], 1135 | "contentType": { 1136 | "sys": { 1137 | "type": "Link", 1138 | "linkType": "ContentType", 1139 | "id": "statItem" 1140 | } 1141 | } 1142 | }, 1143 | "fields": { 1144 | "label": { 1145 | "en-US": "Prefer Ohio-made sandwiches" 1146 | }, 1147 | "value": { 1148 | "en-US": "98%" 1149 | } 1150 | } 1151 | }, 1152 | { 1153 | "metadata": { 1154 | "tags": [ 1155 | ] 1156 | }, 1157 | "sys": { 1158 | "space": { 1159 | "sys": { 1160 | "type": "Link", 1161 | "linkType": "Space", 1162 | "id": "hc8gnoolwanu" 1163 | } 1164 | }, 1165 | "id": "3LwBRMadcjbZOr9AHo2KYM", 1166 | "type": "Entry", 1167 | "createdAt": "2023-12-07T10:53:34.152Z", 1168 | "updatedAt": "2023-12-07T10:53:35.849Z", 1169 | "environment": { 1170 | "sys": { 1171 | "id": "master", 1172 | "type": "Link", 1173 | "linkType": "Environment" 1174 | } 1175 | }, 1176 | "publishedVersion": 1, 1177 | "publishedAt": "2023-12-07T10:53:35.849Z", 1178 | "firstPublishedAt": "2023-12-07T10:53:35.849Z", 1179 | "createdBy": { 1180 | "sys": { 1181 | "type": "Link", 1182 | "linkType": "User", 1183 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1184 | } 1185 | }, 1186 | "updatedBy": { 1187 | "sys": { 1188 | "type": "Link", 1189 | "linkType": "User", 1190 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1191 | } 1192 | }, 1193 | "publishedCounter": 1, 1194 | "version": 2, 1195 | "publishedBy": { 1196 | "sys": { 1197 | "type": "Link", 1198 | "linkType": "User", 1199 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1200 | } 1201 | }, 1202 | "automationTags": [ 1203 | ], 1204 | "contentType": { 1205 | "sys": { 1206 | "type": "Link", 1207 | "linkType": "ContentType", 1208 | "id": "statItem" 1209 | } 1210 | } 1211 | }, 1212 | "fields": { 1213 | "label": { 1214 | "en-US": "Five-star reviews on Yelp" 1215 | }, 1216 | "value": { 1217 | "en-US": "4M" 1218 | } 1219 | } 1220 | }, 1221 | { 1222 | "metadata": { 1223 | "tags": [ 1224 | ] 1225 | }, 1226 | "sys": { 1227 | "space": { 1228 | "sys": { 1229 | "type": "Link", 1230 | "linkType": "Space", 1231 | "id": "hc8gnoolwanu" 1232 | } 1233 | }, 1234 | "id": "36U7omnF7aFEHjVKwEhJI7", 1235 | "type": "Entry", 1236 | "createdAt": "2023-12-07T10:53:34.225Z", 1237 | "updatedAt": "2023-12-07T10:53:35.114Z", 1238 | "environment": { 1239 | "sys": { 1240 | "id": "master", 1241 | "type": "Link", 1242 | "linkType": "Environment" 1243 | } 1244 | }, 1245 | "publishedVersion": 1, 1246 | "publishedAt": "2023-12-07T10:53:35.114Z", 1247 | "firstPublishedAt": "2023-12-07T10:53:35.114Z", 1248 | "createdBy": { 1249 | "sys": { 1250 | "type": "Link", 1251 | "linkType": "User", 1252 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1253 | } 1254 | }, 1255 | "updatedBy": { 1256 | "sys": { 1257 | "type": "Link", 1258 | "linkType": "User", 1259 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1260 | } 1261 | }, 1262 | "publishedCounter": 1, 1263 | "version": 2, 1264 | "publishedBy": { 1265 | "sys": { 1266 | "type": "Link", 1267 | "linkType": "User", 1268 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1269 | } 1270 | }, 1271 | "automationTags": [ 1272 | ], 1273 | "contentType": { 1274 | "sys": { 1275 | "type": "Link", 1276 | "linkType": "ContentType", 1277 | "id": "button" 1278 | } 1279 | } 1280 | }, 1281 | "fields": { 1282 | "label": { 1283 | "en-US": "Book Now" 1284 | }, 1285 | "url": { 1286 | "en-US": "/" 1287 | }, 1288 | "theme": { 1289 | "en-US": "default" 1290 | } 1291 | } 1292 | }, 1293 | { 1294 | "metadata": { 1295 | "tags": [ 1296 | ] 1297 | }, 1298 | "sys": { 1299 | "space": { 1300 | "sys": { 1301 | "type": "Link", 1302 | "linkType": "Space", 1303 | "id": "hc8gnoolwanu" 1304 | } 1305 | }, 1306 | "id": "4pQBscyvi608EAd3KNoxt9", 1307 | "type": "Entry", 1308 | "createdAt": "2023-12-07T10:53:34.844Z", 1309 | "updatedAt": "2023-12-07T10:53:37.414Z", 1310 | "environment": { 1311 | "sys": { 1312 | "id": "master", 1313 | "type": "Link", 1314 | "linkType": "Environment" 1315 | } 1316 | }, 1317 | "publishedVersion": 1, 1318 | "publishedAt": "2023-12-07T10:53:37.414Z", 1319 | "firstPublishedAt": "2023-12-07T10:53:37.414Z", 1320 | "createdBy": { 1321 | "sys": { 1322 | "type": "Link", 1323 | "linkType": "User", 1324 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1325 | } 1326 | }, 1327 | "updatedBy": { 1328 | "sys": { 1329 | "type": "Link", 1330 | "linkType": "User", 1331 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1332 | } 1333 | }, 1334 | "publishedCounter": 1, 1335 | "version": 2, 1336 | "publishedBy": { 1337 | "sys": { 1338 | "type": "Link", 1339 | "linkType": "User", 1340 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1341 | } 1342 | }, 1343 | "automationTags": [ 1344 | ], 1345 | "contentType": { 1346 | "sys": { 1347 | "type": "Link", 1348 | "linkType": "ContentType", 1349 | "id": "page" 1350 | } 1351 | } 1352 | }, 1353 | "fields": { 1354 | "title": { 1355 | "en-US": "Home Page" 1356 | }, 1357 | "slug": { 1358 | "en-US": "/" 1359 | }, 1360 | "sections": { 1361 | "en-US": [ 1362 | { 1363 | "sys": { 1364 | "type": "Link", 1365 | "linkType": "Entry", 1366 | "id": "1waD7wlBFDmDTKcI18NXO0" 1367 | } 1368 | }, 1369 | { 1370 | "sys": { 1371 | "type": "Link", 1372 | "linkType": "Entry", 1373 | "id": "55B39LpWGFDQvt4kYYif6g" 1374 | } 1375 | } 1376 | ] 1377 | } 1378 | } 1379 | } 1380 | ], 1381 | "assets": [ 1382 | { 1383 | "metadata": { 1384 | "tags": [ 1385 | ] 1386 | }, 1387 | "sys": { 1388 | "space": { 1389 | "sys": { 1390 | "type": "Link", 1391 | "linkType": "Space", 1392 | "id": "hc8gnoolwanu" 1393 | } 1394 | }, 1395 | "id": "o1G1j1B3fpZyVGa33M1zJ", 1396 | "type": "Asset", 1397 | "createdAt": "2023-12-07T10:53:30.258Z", 1398 | "updatedAt": "2023-12-07T10:53:33.813Z", 1399 | "environment": { 1400 | "sys": { 1401 | "id": "master", 1402 | "type": "Link", 1403 | "linkType": "Environment" 1404 | } 1405 | }, 1406 | "publishedVersion": 2, 1407 | "publishedAt": "2023-12-07T10:53:33.813Z", 1408 | "firstPublishedAt": "2023-12-07T10:53:33.813Z", 1409 | "createdBy": { 1410 | "sys": { 1411 | "type": "Link", 1412 | "linkType": "User", 1413 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1414 | } 1415 | }, 1416 | "updatedBy": { 1417 | "sys": { 1418 | "type": "Link", 1419 | "linkType": "User", 1420 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1421 | } 1422 | }, 1423 | "publishedCounter": 1, 1424 | "version": 3, 1425 | "publishedBy": { 1426 | "sys": { 1427 | "type": "Link", 1428 | "linkType": "User", 1429 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1430 | } 1431 | } 1432 | }, 1433 | "fields": { 1434 | "title": { 1435 | "en-US": "Sandwich Hero (FPO)" 1436 | }, 1437 | "description": { 1438 | "en-US": "" 1439 | }, 1440 | "file": { 1441 | "en-US": { 1442 | "url": "//images.ctfassets.net/hc8gnoolwanu/o1G1j1B3fpZyVGa33M1zJ/098399e0b62a6e15d8d3cafc6f499bf1/fpo-sandwich.jpg", 1443 | "details": { 1444 | "size": 2148104, 1445 | "image": { 1446 | "width": 5000, 1447 | "height": 4000 1448 | } 1449 | }, 1450 | "fileName": "fpo-sandwich.jpg", 1451 | "contentType": "image/jpeg" 1452 | } 1453 | } 1454 | } 1455 | } 1456 | ], 1457 | "locales": [ 1458 | { 1459 | "name": "English (United States)", 1460 | "code": "en-US", 1461 | "fallbackCode": null, 1462 | "default": true, 1463 | "contentManagementApi": true, 1464 | "contentDeliveryApi": true, 1465 | "optional": false, 1466 | "sys": { 1467 | "type": "Locale", 1468 | "id": "5WHnMHocXDyK4iwSZq2WoX", 1469 | "version": 1, 1470 | "space": { 1471 | "sys": { 1472 | "type": "Link", 1473 | "linkType": "Space", 1474 | "id": "hc8gnoolwanu" 1475 | } 1476 | }, 1477 | "environment": { 1478 | "sys": { 1479 | "type": "Link", 1480 | "linkType": "Environment", 1481 | "id": "master", 1482 | "uuid": "b24b5869-e09a-4fb6-8bc4-e3ea6555ce0e" 1483 | } 1484 | }, 1485 | "createdBy": { 1486 | "sys": { 1487 | "type": "Link", 1488 | "linkType": "User", 1489 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1490 | } 1491 | }, 1492 | "createdAt": "2023-12-07T10:53:22Z", 1493 | "updatedBy": { 1494 | "sys": { 1495 | "type": "Link", 1496 | "linkType": "User", 1497 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1498 | } 1499 | }, 1500 | "updatedAt": "2023-12-07T10:53:22Z" 1501 | } 1502 | } 1503 | ], 1504 | "roles": [ 1505 | { 1506 | "name": "Author", 1507 | "description": "Allows editing of content", 1508 | "policies": [ 1509 | { 1510 | "effect": "allow", 1511 | "actions": [ 1512 | "create" 1513 | ], 1514 | "constraint": { 1515 | "and": [ 1516 | { 1517 | "equals": [ 1518 | { 1519 | "doc": "sys.type" 1520 | }, 1521 | "Entry" 1522 | ] 1523 | } 1524 | ] 1525 | } 1526 | }, 1527 | { 1528 | "effect": "allow", 1529 | "actions": [ 1530 | "read" 1531 | ], 1532 | "constraint": { 1533 | "and": [ 1534 | { 1535 | "equals": [ 1536 | { 1537 | "doc": "sys.type" 1538 | }, 1539 | "Entry" 1540 | ] 1541 | } 1542 | ] 1543 | } 1544 | }, 1545 | { 1546 | "effect": "allow", 1547 | "actions": [ 1548 | "update" 1549 | ], 1550 | "constraint": { 1551 | "and": [ 1552 | { 1553 | "equals": [ 1554 | { 1555 | "doc": "sys.type" 1556 | }, 1557 | "Entry" 1558 | ] 1559 | } 1560 | ] 1561 | } 1562 | }, 1563 | { 1564 | "effect": "allow", 1565 | "actions": [ 1566 | "create" 1567 | ], 1568 | "constraint": { 1569 | "and": [ 1570 | { 1571 | "equals": [ 1572 | { 1573 | "doc": "sys.type" 1574 | }, 1575 | "Asset" 1576 | ] 1577 | } 1578 | ] 1579 | } 1580 | }, 1581 | { 1582 | "effect": "allow", 1583 | "actions": [ 1584 | "read" 1585 | ], 1586 | "constraint": { 1587 | "and": [ 1588 | { 1589 | "equals": [ 1590 | { 1591 | "doc": "sys.type" 1592 | }, 1593 | "Asset" 1594 | ] 1595 | } 1596 | ] 1597 | } 1598 | }, 1599 | { 1600 | "effect": "allow", 1601 | "actions": [ 1602 | "update" 1603 | ], 1604 | "constraint": { 1605 | "and": [ 1606 | { 1607 | "equals": [ 1608 | { 1609 | "doc": "sys.type" 1610 | }, 1611 | "Asset" 1612 | ] 1613 | } 1614 | ] 1615 | } 1616 | } 1617 | ], 1618 | "permissions": { 1619 | "ContentModel": [ 1620 | "read" 1621 | ], 1622 | "Settings": [ 1623 | ], 1624 | "ContentDelivery": [ 1625 | ], 1626 | "Environments": [ 1627 | ], 1628 | "EnvironmentAliases": [ 1629 | ], 1630 | "Tags": [ 1631 | ] 1632 | }, 1633 | "sys": { 1634 | "type": "Role", 1635 | "id": "5XfRVbKPj3jGyMwhdIU2rN", 1636 | "version": 0, 1637 | "space": { 1638 | "sys": { 1639 | "type": "Link", 1640 | "linkType": "Space", 1641 | "id": "hc8gnoolwanu" 1642 | } 1643 | }, 1644 | "createdBy": { 1645 | "sys": { 1646 | "type": "Link", 1647 | "linkType": "User", 1648 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1649 | } 1650 | }, 1651 | "createdAt": "2023-12-07T10:53:22Z", 1652 | "updatedBy": { 1653 | "sys": { 1654 | "type": "Link", 1655 | "linkType": "User", 1656 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1657 | } 1658 | }, 1659 | "updatedAt": "2023-12-07T10:53:22Z" 1660 | } 1661 | }, 1662 | { 1663 | "name": "Editor", 1664 | "description": "Allows editing, publishing and archiving of content", 1665 | "policies": [ 1666 | { 1667 | "effect": "allow", 1668 | "actions": "all", 1669 | "constraint": { 1670 | "and": [ 1671 | { 1672 | "equals": [ 1673 | { 1674 | "doc": "sys.type" 1675 | }, 1676 | "Entry" 1677 | ] 1678 | } 1679 | ] 1680 | } 1681 | }, 1682 | { 1683 | "effect": "allow", 1684 | "actions": "all", 1685 | "constraint": { 1686 | "and": [ 1687 | { 1688 | "equals": [ 1689 | { 1690 | "doc": "sys.type" 1691 | }, 1692 | "Asset" 1693 | ] 1694 | } 1695 | ] 1696 | } 1697 | } 1698 | ], 1699 | "permissions": { 1700 | "ContentModel": [ 1701 | "read" 1702 | ], 1703 | "Settings": [ 1704 | ], 1705 | "ContentDelivery": [ 1706 | ], 1707 | "Environments": [ 1708 | ], 1709 | "EnvironmentAliases": [ 1710 | ], 1711 | "Tags": [ 1712 | ] 1713 | }, 1714 | "sys": { 1715 | "type": "Role", 1716 | "id": "5XgLWiC5LpkbZzAHl0M0bp", 1717 | "version": 0, 1718 | "space": { 1719 | "sys": { 1720 | "type": "Link", 1721 | "linkType": "Space", 1722 | "id": "hc8gnoolwanu" 1723 | } 1724 | }, 1725 | "createdBy": { 1726 | "sys": { 1727 | "type": "Link", 1728 | "linkType": "User", 1729 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1730 | } 1731 | }, 1732 | "createdAt": "2023-12-07T10:53:22Z", 1733 | "updatedBy": { 1734 | "sys": { 1735 | "type": "Link", 1736 | "linkType": "User", 1737 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1738 | } 1739 | }, 1740 | "updatedAt": "2023-12-07T10:53:22Z" 1741 | } 1742 | }, 1743 | { 1744 | "name": "Translator", 1745 | "description": "Allows editing of localized fields in the specified language", 1746 | "policies": [ 1747 | { 1748 | "effect": "allow", 1749 | "actions": [ 1750 | "read" 1751 | ], 1752 | "constraint": { 1753 | "and": [ 1754 | { 1755 | "equals": [ 1756 | { 1757 | "doc": "sys.type" 1758 | }, 1759 | "Entry" 1760 | ] 1761 | } 1762 | ] 1763 | } 1764 | }, 1765 | { 1766 | "effect": "allow", 1767 | "actions": [ 1768 | "read" 1769 | ], 1770 | "constraint": { 1771 | "and": [ 1772 | { 1773 | "equals": [ 1774 | { 1775 | "doc": "sys.type" 1776 | }, 1777 | "Asset" 1778 | ] 1779 | } 1780 | ] 1781 | } 1782 | }, 1783 | { 1784 | "effect": "allow", 1785 | "actions": [ 1786 | "update" 1787 | ], 1788 | "constraint": { 1789 | "and": [ 1790 | { 1791 | "equals": [ 1792 | { 1793 | "doc": "sys.type" 1794 | }, 1795 | "Entry" 1796 | ] 1797 | }, 1798 | { 1799 | "paths": [ 1800 | { 1801 | "doc": "fields.%.%" 1802 | } 1803 | ] 1804 | } 1805 | ] 1806 | } 1807 | }, 1808 | { 1809 | "effect": "allow", 1810 | "actions": [ 1811 | "update" 1812 | ], 1813 | "constraint": { 1814 | "and": [ 1815 | { 1816 | "equals": [ 1817 | { 1818 | "doc": "sys.type" 1819 | }, 1820 | "Asset" 1821 | ] 1822 | }, 1823 | { 1824 | "paths": [ 1825 | { 1826 | "doc": "fields.%.%" 1827 | } 1828 | ] 1829 | } 1830 | ] 1831 | } 1832 | } 1833 | ], 1834 | "permissions": { 1835 | "ContentModel": [ 1836 | "read" 1837 | ], 1838 | "Settings": [ 1839 | ], 1840 | "ContentDelivery": [ 1841 | ], 1842 | "Environments": [ 1843 | ], 1844 | "EnvironmentAliases": [ 1845 | ], 1846 | "Tags": [ 1847 | ] 1848 | }, 1849 | "sys": { 1850 | "type": "Role", 1851 | "id": "5XhdBQ5Fe2l8eV5yUnUWnV", 1852 | "version": 0, 1853 | "space": { 1854 | "sys": { 1855 | "type": "Link", 1856 | "linkType": "Space", 1857 | "id": "hc8gnoolwanu" 1858 | } 1859 | }, 1860 | "createdBy": { 1861 | "sys": { 1862 | "type": "Link", 1863 | "linkType": "User", 1864 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1865 | } 1866 | }, 1867 | "createdAt": "2023-12-07T10:53:22Z", 1868 | "updatedBy": { 1869 | "sys": { 1870 | "type": "Link", 1871 | "linkType": "User", 1872 | "id": "1JaKkSjxX8SGAGTUKV3JYB" 1873 | } 1874 | }, 1875 | "updatedAt": "2023-12-07T10:53:22Z" 1876 | } 1877 | } 1878 | ] 1879 | } --------------------------------------------------------------------------------