[examples] Add a statically generated blog example using Next.js and Builder.io (#22094)
A statically generated blog example using Next.js and [Builder.io](https://builder.io), demo on [https://cms-builder-io.vercel.app/](https://cms-builder-blog.vercel.app/)
|
@ -63,6 +63,7 @@ You can also use **Client-side Rendering** along with Static Generation or Serve
|
|||
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-storyblok">Storyblok Example</a> (<a href="https://next-blog-storyblok.vercel.app/">Demo</a>)</li>
|
||||
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-graphcms">GraphCMS Example</a> (<a href="https://next-blog-graphcms.vercel.app/">Demo</a>)</li>
|
||||
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-kontent">Kontent Example</a> (<a href="https://next-blog-kontent.vercel.app/">Demo</a>)</li>
|
||||
<li><a href="https://github.com/vercel/next.js/tree/canary/examples/cms-builder-io">Builder.io Example</a> (<a href="https://cms-builder-io.vercel.app/">Demo</a>)</li>
|
||||
<li><a href="https://static-tweet.vercel.app/">Static Tweet (Demo)</a></li>
|
||||
</ul>
|
||||
</details>
|
||||
|
|
|
@ -38,6 +38,7 @@ Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_mediu
|
|||
- [GraphCMS](/examples/cms-graphcms)
|
||||
- [Kontent](/examples/cms-kontent)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ Once you have access to [the environment variables you'll need](#step-15-set-up-
|
|||
- [Ghost](/examples/cms-ghost)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|
2
examples/cms-builder-io/.env.local.example
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Copy this file as .env.local
|
||||
NEXT_PUBLIC_BUILDER_API_KEY=
|
34
examples/cms-builder-io/.gitignore
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
93
examples/cms-builder-io/README.md
Normal file
|
@ -0,0 +1,93 @@
|
|||
# A statically generated blog example using Next.js and Builder.io
|
||||
|
||||
This example showcases Next.js's [Static Generation](https://nextjs.org/docs/basic-features/pages) feature using [Builder.io](https://builder.io/) as the data source.
|
||||
|
||||
## Demo
|
||||
|
||||
[https://cms-builder-io.vercel.app/](https://cms-builder-io.vercel.app/)
|
||||
|
||||
## How to use
|
||||
|
||||
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
|
||||
|
||||
```bash
|
||||
npx create-next-app --example cms-builder-io cms-builder-io-app
|
||||
# or
|
||||
yarn create next-app --example cms-builder-io cms-builder-io-app
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Step 1 Install the Builder.io cli
|
||||
|
||||
```
|
||||
npm install @builder.io/cli -g
|
||||
```
|
||||
|
||||
### Step 2 Generate a space
|
||||
|
||||
[Signup for Builder.io](https://builder.io/signup), then go to your [organization settings page](https://builder.io/account/organization?root=true), create a private key and copy it and supply it for `[private-key]` below. For `[space-name]` create a name for your space, such as "Blog"
|
||||
|
||||
```
|
||||
cd cms-builder-io-app
|
||||
builder create -k [private-key] -n [space-name] -d
|
||||
```
|
||||
|
||||
This command when done it'll print your new space's public api key, copy it and add as the value for `NEXT_PUBLIC_BUILDER_API_KEY` into the .env files (`.env.production` and `.env.development`)
|
||||
|
||||
```
|
||||
BUILDER_PUBLIC_KEY=...
|
||||
```
|
||||
|
||||
### Step 3 Run Next.js in development mode
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
|
||||
# or
|
||||
|
||||
yarn install
|
||||
yarn dev
|
||||
```
|
||||
|
||||
Your blog should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, you can post on [GitHub discussions](https://github.com/vercel/next.js/discussions).
|
||||
|
||||
### Step 4 Try preview mode
|
||||
|
||||
To try preview mode at any time while editing in Builder.io press `view current draft`, if you changed the secret defined in [constants.js](./lib/constants.js) you'll need to also change it in your `Post` [model settings](https://builder.io/models).
|
||||
|
||||
To exit the preview mode, you can click **Click here to exit preview mode** at the top.
|
||||
|
||||
### Step 5 Deploy on Vercel
|
||||
|
||||
You can deploy this app to the cloud with [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
|
||||
|
||||
#### Deploy Your Local Project
|
||||
|
||||
To deploy your local project to Vercel, push it to GitHub/GitLab/Bitbucket and [import to Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example).
|
||||
|
||||
**Important**: When you import your project on Vercel, make sure to click on **Environment Variables** and set them to match your `.env.local` file.
|
||||
|
||||
#### Deploy from Our Template
|
||||
|
||||
Alternatively, you can deploy using our template by clicking on the Deploy button below.
|
||||
|
||||
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/cms-builder-io&project-name=cms-builder-io&repository-name=cms-builder-io&env=BUILDER_PUBLIC_KEY&envDescription=Required%20to%20connect%20the%20app%20with%20Builder.io&envLink=https://www.builder.io/c/docs/custom-react-components#api-key)
|
||||
|
||||
### Related examples
|
||||
|
||||
- [WordPress](/examples/cms-wordpress)
|
||||
- [DatoCMS](/examples/cms-datocms)
|
||||
- [Sanity](/examples/cms-sanity)
|
||||
- [TakeShape](/examples/cms-takeshape)
|
||||
- [Prismic](/examples/cms-prismic)
|
||||
- [Contentful](/examples/cms-contentful)
|
||||
- [Agility CMS](/examples/cms-agilitycms)
|
||||
- [Cosmic](/examples/cms-cosmic)
|
||||
- [Strapi](/examples/cms-strapi)
|
||||
- [ButterCMS](/examples/cms-buttercms)
|
||||
- [GraphCMS](/examples/cms-graphcms)
|
||||
- [Kontent](/examples/cms-kontent)
|
||||
- [Ghost](/examples/cms-ghost)
|
||||
- [Blog Starter](/examples/blog-starter)
|
24
examples/cms-builder-io/builder/author/joe-public.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"createdBy": "4FFFg0MNRJT0z0nW4uUizDHfHJV2",
|
||||
"createdDate": 1613015350978,
|
||||
"data": {
|
||||
"image": "https://cdn.builder.io/api/v1/image/assets%2F8f6bae86bfa3487eb1a18f263118c832%2F6ae860242834453ea87d6057e7df9754",
|
||||
"name": "Joe Public"
|
||||
},
|
||||
"id": "7b0b333bd44b4e91a6f4bf93158cb62b",
|
||||
"lastUpdatedBy": "4FFFg0MNRJT0z0nW4uUizDHfHJV2",
|
||||
"meta": {
|
||||
"kind": "data"
|
||||
},
|
||||
"modelId": "6d30b724c93d4198b0c0ce2d3ce390dc",
|
||||
"name": "Joe Public",
|
||||
"published": "published",
|
||||
"query": [],
|
||||
"testRatio": 1,
|
||||
"variations": {},
|
||||
"lastUpdated": 1613031369279,
|
||||
"rev": "0pjukbnd3ox",
|
||||
"@originOrg": "8f6bae86bfa3487eb1a18f263118c832",
|
||||
"@originContentId": "ba1fb5129adf4c379424d346666cc092",
|
||||
"@originModelId": "c71bab5b43fa42eca870e330a39b59e0"
|
||||
}
|
24
examples/cms-builder-io/builder/author/johnny-doe.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"createdBy": "4FFFg0MNRJT0z0nW4uUizDHfHJV2",
|
||||
"createdDate": 1613027534444,
|
||||
"data": {
|
||||
"image": "https://cdn.builder.io/api/v1/image/assets%2F8f6bae86bfa3487eb1a18f263118c832%2F5df565e2c411421082123ea8c1084a73",
|
||||
"name": "Johnny Roe"
|
||||
},
|
||||
"id": "d50fe8eced654b2dae22c738dbeabcee",
|
||||
"lastUpdatedBy": "4FFFg0MNRJT0z0nW4uUizDHfHJV2",
|
||||
"meta": {
|
||||
"kind": "data"
|
||||
},
|
||||
"modelId": "6d30b724c93d4198b0c0ce2d3ce390dc",
|
||||
"name": "Johnny Doe",
|
||||
"published": "published",
|
||||
"query": [],
|
||||
"testRatio": 1,
|
||||
"variations": {},
|
||||
"lastUpdated": 1613067837951,
|
||||
"rev": "0pjukbnd3ox",
|
||||
"@originOrg": "8f6bae86bfa3487eb1a18f263118c832",
|
||||
"@originContentId": "edcaddd1a70f494ba1955704cd88ca4f",
|
||||
"@originModelId": "c71bab5b43fa42eca870e330a39b59e0"
|
||||
}
|
96
examples/cms-builder-io/builder/author/schema.model.json
Normal file
|
@ -0,0 +1,96 @@
|
|||
{
|
||||
"helperText": "",
|
||||
"injectWcAt": "",
|
||||
"webhooks": [],
|
||||
"showTargeting": true,
|
||||
"sendToMongoDb": true,
|
||||
"hideFromUI": false,
|
||||
"showScheduling": true,
|
||||
"name": "author",
|
||||
"fields": [
|
||||
{
|
||||
"showTemplatePicker": true,
|
||||
"helperText": "",
|
||||
"type": "text",
|
||||
"name": "name",
|
||||
"noPhotoPicker": false,
|
||||
"simpleTextOnly": false,
|
||||
"permissionsRequiredToEdit": "",
|
||||
"@type": "@builder.io/core:Field",
|
||||
"mandatory": false,
|
||||
"required": true,
|
||||
"hideFromFieldsEditor": false,
|
||||
"hideFromUI": false,
|
||||
"model": "",
|
||||
"copyOnAdd": true,
|
||||
"disallowRemove": false,
|
||||
"showIf": "",
|
||||
"advanced": false,
|
||||
"onChange": "",
|
||||
"subFields": [],
|
||||
"autoFocus": false,
|
||||
"hidden": false
|
||||
},
|
||||
{
|
||||
"autoFocus": false,
|
||||
"subFields": [],
|
||||
"name": "image",
|
||||
"required": true,
|
||||
"type": "file",
|
||||
"allowedFileTypes": ["jpeg", "png"],
|
||||
"@type": "@builder.io/core:Field",
|
||||
"copyOnAdd": true,
|
||||
"defaultValue": "https://cdn.builder.io/api/v1/image/assets%2F8f6bae86bfa3487eb1a18f263118c832%2F8c8bf9b14266412497c0090aa3136beb",
|
||||
"showTemplatePicker": true,
|
||||
"noPhotoPicker": false,
|
||||
"mandatory": false,
|
||||
"disallowRemove": false,
|
||||
"showIf": "",
|
||||
"permissionsRequiredToEdit": "",
|
||||
"advanced": false,
|
||||
"onChange": "",
|
||||
"model": "",
|
||||
"hideFromFieldsEditor": false,
|
||||
"hideFromUI": false,
|
||||
"helperText": "",
|
||||
"hidden": false,
|
||||
"simpleTextOnly": false
|
||||
}
|
||||
],
|
||||
"publicReadable": true,
|
||||
"individualEmbed": false,
|
||||
"schema": {},
|
||||
"lastUpdateBy": null,
|
||||
"subType": "",
|
||||
"id": "6d30b724c93d4198b0c0ce2d3ce390dc",
|
||||
"injectWcPosition": "",
|
||||
"repeatable": false,
|
||||
"archived": false,
|
||||
"hooks": {},
|
||||
"pathPrefix": "/",
|
||||
"requiredTargets": [],
|
||||
"allowBuiltInComponents": true,
|
||||
"isPage": false,
|
||||
"publicWritable": false,
|
||||
"autoTracked": true,
|
||||
"sendToElasticSearch": false,
|
||||
"hideOptions": false,
|
||||
"examplePageUrl": "",
|
||||
"showAbTests": true,
|
||||
"allowTests": true,
|
||||
"getSchemaFromPage": false,
|
||||
"allowMetrics": true,
|
||||
"defaultQuery": [],
|
||||
"useQueryParamTargetingClientSide": false,
|
||||
"kind": "data",
|
||||
"designerVersion": 1,
|
||||
"strictPrivateWrite": false,
|
||||
"componentsOnlyMode": false,
|
||||
"showMetrics": true,
|
||||
"singleton": false,
|
||||
"bigData": false,
|
||||
"hidden": false,
|
||||
"allowHeatmap": true,
|
||||
"strictPrivateRead": false,
|
||||
"@originId": "c71bab5b43fa42eca870e330a39b59e0"
|
||||
}
|
283
examples/cms-builder-io/builder/post/first-one.json
Normal file
|
@ -0,0 +1,283 @@
|
|||
{
|
||||
"createdBy": "4FFFg0MNRJT0z0nW4uUizDHfHJV2",
|
||||
"createdDate": 1613015962185,
|
||||
"data": {
|
||||
"author": {
|
||||
"@type": "@builder.io/core:Reference",
|
||||
"id": "d50fe8eced654b2dae22c738dbeabcee",
|
||||
"model": "author"
|
||||
},
|
||||
"image": "https://cdn.builder.io/api/v1/image/assets%2F8f6bae86bfa3487eb1a18f263118c832%2F79e961dbf6d54a9a8f189c5bd48454d8",
|
||||
"inputs": [],
|
||||
"intro": "pellentesque nec nam aliquam. Tincidunt id aliquet risus feugiat in ante metus dictum at. Nascetur ridiculus mus mauris vitae ultricies leo integer malesuada nunc. Tellus cras adipiscing enim eu turpis. Ultrices eros in cursus turpis massa tincidunt dui. Feugiat nisl pretium fusce id. Mauris augue neque gravida infermentum et. Sed elementum tempus egestas sed. At consectetur lorem donec massa sapien faucibus et.",
|
||||
"slug": "first-one",
|
||||
"title": "Now howoiofweewf",
|
||||
"blocks": [
|
||||
{
|
||||
"@type": "@builder.io/sdk:Element",
|
||||
"@version": 2,
|
||||
"id": "builder-73d17ca4f7bc472dbd5b146c075d7976",
|
||||
"component": {
|
||||
"name": "Core:Section",
|
||||
"options": {
|
||||
"maxWidth": 1200
|
||||
}
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"@type": "@builder.io/sdk:Element",
|
||||
"@version": 2,
|
||||
"id": "builder-2ac544bf3b9941b2b4e629e34e44c069",
|
||||
"component": {
|
||||
"name": "Columns",
|
||||
"options": {
|
||||
"columns": [
|
||||
{
|
||||
"blocks": [
|
||||
{
|
||||
"@type": "@builder.io/sdk:Element",
|
||||
"@version": 2,
|
||||
"layerName": "Centered Box",
|
||||
"id": "builder-90ecefea6830467787059c4a74a67bc9",
|
||||
"children": [
|
||||
{
|
||||
"@type": "@builder.io/sdk:Element",
|
||||
"@version": 2,
|
||||
"layerName": "Title",
|
||||
"id": "builder-86d8df34f7924d90b1f0326f644f3dd6",
|
||||
"component": {
|
||||
"name": "Text",
|
||||
"options": {
|
||||
"text": "<p>Something Great to Say</p>"
|
||||
}
|
||||
},
|
||||
"responsiveStyles": {
|
||||
"large": {
|
||||
"display": "flex",
|
||||
"flexDirection": "column",
|
||||
"alignItems": "stretch",
|
||||
"flexShrink": "0",
|
||||
"position": "relative",
|
||||
"marginTop": "-1.65625px",
|
||||
"textAlign": "center",
|
||||
"lineHeight": "normal",
|
||||
"height": "auto",
|
||||
"fontSize": "33px"
|
||||
},
|
||||
"medium": {
|
||||
"marginTop": "29.34375px",
|
||||
"textAlign": "center"
|
||||
},
|
||||
"small": {
|
||||
"fontSize": "25px"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "@builder.io/sdk:Element",
|
||||
"@version": 2,
|
||||
"layerName": "Subtitle",
|
||||
"id": "builder-796f2f44186e4206ad59bde67dcd969c",
|
||||
"component": {
|
||||
"name": "Text",
|
||||
"options": {
|
||||
"text": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Orci sagittis eu volutpat odio facilisis mauris. Commodo nulla facilisi nullam vehicula. Tellus cras adipiscing enim eu. Morbi blandit cursus risus at ultrices mi tempus imperdiet nulla. Tempus quam pellentesque nec nam aliquam. Tincidunt id aliquet risus feugiat in ante metus dictum at. Nascetur ridiculus mus mauris vitae ultricies leo integer malesuada nunc. Tellus cras adipiscing enim eu turpis. Ultrices eros in cursus turpis massa tincidunt dui. Feugiat nisl pretium fusce id. Mauris augue neque gravida infermentum et. Sed elementum tempus egestas sed. At consectetur lorem donec massa sapien faucibus et. Tellus pellentesque eu tincidunt tortor. Blandit turpis cursus in hac habitasse. Dui nunc mattis enim ut tellus elementum sagittis vitae.</p>"
|
||||
}
|
||||
},
|
||||
"responsiveStyles": {
|
||||
"large": {
|
||||
"display": "flex",
|
||||
"flexDirection": "column",
|
||||
"alignItems": "stretch",
|
||||
"flexShrink": "0",
|
||||
"position": "relative",
|
||||
"marginTop": "25.59375px",
|
||||
"textAlign": "center",
|
||||
"lineHeight": "normal",
|
||||
"height": "auto",
|
||||
"fontSize": "17px",
|
||||
"color": "rgba(86, 86, 86, 1)"
|
||||
},
|
||||
"medium": {
|
||||
"textAlign": "center"
|
||||
},
|
||||
"small": {
|
||||
"fontSize": "15px"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "@builder.io/sdk:Element",
|
||||
"@version": 2,
|
||||
"id": "builder-f299f4294fbb46659a49c44f230ae1e0",
|
||||
"component": {
|
||||
"name": "Core:Button",
|
||||
"options": {
|
||||
"text": "Let's go"
|
||||
}
|
||||
},
|
||||
"responsiveStyles": {
|
||||
"large": {
|
||||
"display": "flex",
|
||||
"flexDirection": "column",
|
||||
"alignItems": "stretch",
|
||||
"position": "relative",
|
||||
"flexShrink": "0",
|
||||
"boxSizing": "border-box",
|
||||
"marginTop": "26px",
|
||||
"appearance": "none",
|
||||
"paddingTop": "15px",
|
||||
"paddingBottom": "15px",
|
||||
"paddingLeft": "31px",
|
||||
"paddingRight": "31px",
|
||||
"backgroundColor": "rgba(50, 50, 50, 1)",
|
||||
"color": "white",
|
||||
"borderRadius": "4px",
|
||||
"textAlign": "center",
|
||||
"marginLeft": "auto",
|
||||
"marginRight": "auto",
|
||||
"cursor": "pointer"
|
||||
},
|
||||
"medium": {
|
||||
"marginLeft": "auto",
|
||||
"marginRight": "auto"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responsiveStyles": {
|
||||
"large": {
|
||||
"display": "flex",
|
||||
"flexDirection": "column",
|
||||
"alignItems": "stretch",
|
||||
"position": "relative",
|
||||
"flexShrink": "0",
|
||||
"boxSizing": "border-box",
|
||||
"marginTop": "auto",
|
||||
"marginBottom": "auto",
|
||||
"paddingBottom": "16px"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"blocks": [
|
||||
{
|
||||
"@type": "@builder.io/sdk:Element",
|
||||
"@version": 2,
|
||||
"id": "builder-104a7e15a7d648e6896fbc98cc9b17ed",
|
||||
"component": {
|
||||
"name": "Image",
|
||||
"options": {
|
||||
"image": "https://cdn.builder.io/api/v1/image/assets%2FagZ9n5CUKRfbL9t6CaJOyVSK4Es2%2F975106936a734566974059059f54ec8d?width=2000&height=1000",
|
||||
"backgroundPosition": "center",
|
||||
"backgroundSize": "cover",
|
||||
"aspectRatio": 0.7004048582995948
|
||||
}
|
||||
},
|
||||
"responsiveStyles": {
|
||||
"large": {
|
||||
"display": "flex",
|
||||
"flexDirection": "column",
|
||||
"alignItems": "stretch",
|
||||
"flexShrink": "0",
|
||||
"position": "relative",
|
||||
"marginTop": "-2.5px",
|
||||
"textAlign": "center",
|
||||
"lineHeight": "normal",
|
||||
"height": "auto"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"space": 42,
|
||||
"stackColumnsAt": "tablet",
|
||||
"reverseColumnsWhenStacked": true
|
||||
}
|
||||
},
|
||||
"responsiveStyles": {
|
||||
"large": {
|
||||
"display": "flex",
|
||||
"flexDirection": "column",
|
||||
"alignItems": "stretch",
|
||||
"position": "relative",
|
||||
"flexShrink": "0",
|
||||
"boxSizing": "border-box",
|
||||
"marginTop": "2.34375px",
|
||||
"paddingLeft": "0px",
|
||||
"paddingRight": "0px"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"responsiveStyles": {
|
||||
"large": {
|
||||
"display": "flex",
|
||||
"flexDirection": "column",
|
||||
"alignItems": "stretch",
|
||||
"position": "relative",
|
||||
"flexShrink": "0",
|
||||
"boxSizing": "border-box",
|
||||
"marginTop": "0px",
|
||||
"paddingLeft": "20px",
|
||||
"paddingRight": "20px",
|
||||
"paddingTop": "50px",
|
||||
"paddingBottom": "50px",
|
||||
"width": "100vw",
|
||||
"marginLeft": "calc(50% - 50vw)"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "builder-pixel-3zydvairp32",
|
||||
"@type": "@builder.io/sdk:Element",
|
||||
"tagName": "img",
|
||||
"properties": {
|
||||
"src": "https://cdn.builder.io/api/v1/pixel?apiKey=8f6bae86bfa3487eb1a18f263118c832",
|
||||
"role": "presentation",
|
||||
"width": "0",
|
||||
"height": "0"
|
||||
},
|
||||
"responsiveStyles": {
|
||||
"large": {
|
||||
"height": "0",
|
||||
"width": "0",
|
||||
"display": "inline-block",
|
||||
"opacity": "0",
|
||||
"overflow": "hidden",
|
||||
"pointerEvents": "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"state": {
|
||||
"deviceSize": "large",
|
||||
"location": {
|
||||
"path": "",
|
||||
"query": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "006452f51b414da189e8ccc576d9805b",
|
||||
"lastUpdatedBy": "agZ9n5CUKRfbL9t6CaJOyVSK4Es2",
|
||||
"meta": {
|
||||
"hasLinks": false,
|
||||
"kind": "component",
|
||||
"needsHydration": false
|
||||
},
|
||||
"modelId": "3f6eda812cf2484088b1451a2150d38f",
|
||||
"name": "first one",
|
||||
"published": "published",
|
||||
"query": [],
|
||||
"testRatio": 1,
|
||||
"variations": {},
|
||||
"lastUpdated": 1613035917446,
|
||||
"screenshot": "https://cdn.builder.io/api/v1/image/assets%2F8f6bae86bfa3487eb1a18f263118c832%2Ffb7a0bb3ded54a8cbcdd8ddd98d24a7e",
|
||||
"rev": "3mj2dvbqtry",
|
||||
"@originOrg": "8f6bae86bfa3487eb1a18f263118c832",
|
||||
"@originContentId": "e7951ec30b1c496b87b3fa2c98192a79",
|
||||
"@originModelId": "7a732bbf5d964e7bbeff4acef2735c8a"
|
||||
}
|
197
examples/cms-builder-io/builder/post/schema.model.json
Normal file
|
@ -0,0 +1,197 @@
|
|||
{
|
||||
"requiredTargets": [],
|
||||
"publicWritable": false,
|
||||
"fields": [
|
||||
{
|
||||
"noPhotoPicker": false,
|
||||
"permissionsRequiredToEdit": "",
|
||||
"required": true,
|
||||
"hideFromUI": false,
|
||||
"onChange": "",
|
||||
"hidden": false,
|
||||
"autoFocus": false,
|
||||
"hideFromFieldsEditor": true,
|
||||
"simpleTextOnly": false,
|
||||
"name": "blocks",
|
||||
"mandatory": false,
|
||||
"showTemplatePicker": true,
|
||||
"showIf": "",
|
||||
"advanced": false,
|
||||
"copyOnAdd": true,
|
||||
"subFields": [],
|
||||
"model": "",
|
||||
"disallowRemove": false,
|
||||
"@type": "@builder.io/core:Field",
|
||||
"type": "uiBlocks",
|
||||
"helperText": ""
|
||||
},
|
||||
{
|
||||
"showIf": "",
|
||||
"copyOnAdd": true,
|
||||
"showTemplatePicker": true,
|
||||
"hideFromFieldsEditor": false,
|
||||
"advanced": false,
|
||||
"type": "text",
|
||||
"model": "",
|
||||
"hidden": false,
|
||||
"disallowRemove": false,
|
||||
"hideFromUI": false,
|
||||
"permissionsRequiredToEdit": "",
|
||||
"onChange": "",
|
||||
"subFields": [],
|
||||
"simpleTextOnly": false,
|
||||
"name": "title",
|
||||
"required": true,
|
||||
"defaultValue": "Blog title",
|
||||
"autoFocus": false,
|
||||
"noPhotoPicker": false,
|
||||
"@type": "@builder.io/core:Field",
|
||||
"mandatory": false,
|
||||
"helperText": ""
|
||||
},
|
||||
{
|
||||
"showIf": "",
|
||||
"mandatory": false,
|
||||
"defaultValue": "https://cdn.builder.io/api/v1/image/assets%2F8f6bae86bfa3487eb1a18f263118c832%2Fb5d394eb6ab342a0a2f2de8ef2ba496a",
|
||||
"copyOnAdd": true,
|
||||
"hideFromUI": false,
|
||||
"hidden": false,
|
||||
"autoFocus": false,
|
||||
"type": "file",
|
||||
"allowedFileTypes": ["jpeg", "png"],
|
||||
"onChange": "",
|
||||
"showTemplatePicker": true,
|
||||
"model": "",
|
||||
"hideFromFieldsEditor": false,
|
||||
"disallowRemove": false,
|
||||
"permissionsRequiredToEdit": "",
|
||||
"subFields": [],
|
||||
"name": "image",
|
||||
"advanced": false,
|
||||
"required": false,
|
||||
"simpleTextOnly": false,
|
||||
"noPhotoPicker": false,
|
||||
"helperText": "open graph image",
|
||||
"@type": "@builder.io/core:Field"
|
||||
},
|
||||
{
|
||||
"permissionsRequiredToEdit": "",
|
||||
"@type": "@builder.io/core:Field",
|
||||
"subFields": [],
|
||||
"copyOnAdd": true,
|
||||
"hideFromUI": false,
|
||||
"modelId": "6d30b724c93d4198b0c0ce2d3ce390dc",
|
||||
"simpleTextOnly": false,
|
||||
"helperText": "Author of the post",
|
||||
"showIf": "",
|
||||
"noPhotoPicker": false,
|
||||
"mandatory": false,
|
||||
"showTemplatePicker": true,
|
||||
"onChange": "",
|
||||
"advanced": false,
|
||||
"type": "reference",
|
||||
"autoFocus": false,
|
||||
"model": "",
|
||||
"hidden": false,
|
||||
"required": true,
|
||||
"defaultValue": {
|
||||
"id": "7b0b333bd44b4e91a6f4bf93158cb62b",
|
||||
"model": "author",
|
||||
"@type": "@builder.io/core:Reference"
|
||||
},
|
||||
"name": "author",
|
||||
"hideFromFieldsEditor": false,
|
||||
"disallowRemove": false
|
||||
},
|
||||
{
|
||||
"showIf": "",
|
||||
"helperText": "",
|
||||
"showTemplatePicker": true,
|
||||
"disallowRemove": false,
|
||||
"autoFocus": false,
|
||||
"hideFromFieldsEditor": false,
|
||||
"mandatory": false,
|
||||
"hidden": false,
|
||||
"onChange": "",
|
||||
"name": "intro",
|
||||
"simpleTextOnly": false,
|
||||
"permissionsRequiredToEdit": "",
|
||||
"@type": "@builder.io/core:Field",
|
||||
"hideFromUI": false,
|
||||
"type": "longText",
|
||||
"advanced": false,
|
||||
"defaultValue": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Orci sagittis eu volutpat odio facilisis mauris. Commodo nulla facilisi nullam vehicula. Tellus cras adipiscing enim eu. Morbi blandit cursus risus at ultrices mi tempus imperdiet nulla. Tempus quam pellentesque nec nam aliquam. Tincidunt id aliquet risus feugiat in ante metus dictum at. Nascetur ridiculus mus mauris vitae ultricies leo integer malesuada nunc. Tellus cras adipiscing enim eu turpis. Ultrices eros in cursus turpis massa tincidunt dui. Feugiat nisl pretium fusce id. Mauris augue neque gravida in fermentum et. Sed elementum tempus egestas sed. At consectetur lorem donec massa sapien faucibus et. Tellus pellentesque eu tincidunt tortor. Blandit turpis cursus in hac habitasse. Dui nunc mattis enim ut tellus elementum sagittis vitae.",
|
||||
"copyOnAdd": true,
|
||||
"required": false,
|
||||
"noPhotoPicker": false,
|
||||
"subFields": [],
|
||||
"model": ""
|
||||
},
|
||||
{
|
||||
"permissionsRequiredToEdit": "",
|
||||
"defaultValue": "default-one",
|
||||
"helperText": "",
|
||||
"hideFromFieldsEditor": false,
|
||||
"required": true,
|
||||
"subFields": [],
|
||||
"noPhotoPicker": false,
|
||||
"advanced": false,
|
||||
"onChange": "",
|
||||
"showIf": "",
|
||||
"hidden": false,
|
||||
"mandatory": false,
|
||||
"model": "",
|
||||
"name": "slug",
|
||||
"hideFromUI": false,
|
||||
"type": "text",
|
||||
"@type": "@builder.io/core:Field",
|
||||
"simpleTextOnly": false,
|
||||
"showTemplatePicker": true,
|
||||
"copyOnAdd": true,
|
||||
"disallowRemove": false,
|
||||
"autoFocus": false
|
||||
}
|
||||
],
|
||||
"sendToMongoDb": true,
|
||||
"archived": false,
|
||||
"componentsOnlyMode": false,
|
||||
"autoTracked": true,
|
||||
"allowTests": true,
|
||||
"showScheduling": true,
|
||||
"designerVersion": 1,
|
||||
"getSchemaFromPage": false,
|
||||
"injectWcAt": "",
|
||||
"sendToElasticSearch": false,
|
||||
"individualEmbed": false,
|
||||
"hidden": false,
|
||||
"injectWcPosition": "",
|
||||
"webhooks": [],
|
||||
"showTargeting": true,
|
||||
"allowMetrics": true,
|
||||
"showMetrics": true,
|
||||
"subType": "",
|
||||
"allowHeatmap": true,
|
||||
"showAbTests": true,
|
||||
"pathPrefix": "/",
|
||||
"id": "3f6eda812cf2484088b1451a2150d38f",
|
||||
"isPage": false,
|
||||
"kind": "component",
|
||||
"repeatable": false,
|
||||
"lastUpdateBy": null,
|
||||
"hooks": {},
|
||||
"hideOptions": false,
|
||||
"strictPrivateRead": false,
|
||||
"strictPrivateWrite": false,
|
||||
"hideFromUI": false,
|
||||
"examplePageUrl": "http://localhost:3000/api/preview?secret=micky-mouse",
|
||||
"allowBuiltInComponents": true,
|
||||
"name": "post",
|
||||
"singleton": false,
|
||||
"useQueryParamTargetingClientSide": false,
|
||||
"publicReadable": true,
|
||||
"defaultQuery": [],
|
||||
"helperText": "",
|
||||
"bigData": false,
|
||||
"schema": {},
|
||||
"@originId": "7a732bbf5d964e7bbeff4acef2735c8a"
|
||||
}
|
1293
examples/cms-builder-io/builder/post/second.json
Normal file
21
examples/cms-builder-io/builder/settings.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"hasIntegrated": "local",
|
||||
"siteUrl": "http://localhost:3000",
|
||||
"type": "space",
|
||||
"name": "blog-test",
|
||||
"@version": 5,
|
||||
"cloneInfo": {
|
||||
"contentIdMap": {
|
||||
"ba1fb5129adf4c379424d346666cc092": "7b0b333bd44b4e91a6f4bf93158cb62b",
|
||||
"edcaddd1a70f494ba1955704cd88ca4f": "d50fe8eced654b2dae22c738dbeabcee",
|
||||
"a9670a29beb04ab98fa9ad87da782363": "c9a48699668448daa6988f2fcad3cd34",
|
||||
"e7951ec30b1c496b87b3fa2c98192a79": "006452f51b414da189e8ccc576d9805b",
|
||||
"3ff20a4db1994618bb45ac7c8610300f": "aa5cde0446204c228a11ea6ff10fff92"
|
||||
},
|
||||
"modelIdMap": {
|
||||
"c71bab5b43fa42eca870e330a39b59e0": "6d30b724c93d4198b0c0ce2d3ce390dc",
|
||||
"06fbdb4d7ab6473f8ec8afad46acaa2a": "7f355eb3798c4d4286a5d12e8f0a3009",
|
||||
"7a732bbf5d964e7bbeff4acef2735c8a": "3f6eda812cf2484088b1451a2150d38f"
|
||||
}
|
||||
}
|
||||
}
|
42
examples/cms-builder-io/components/alert.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
import Container from './container'
|
||||
import cn from 'classnames'
|
||||
import { EXAMPLE_PATH } from '../lib/constants'
|
||||
|
||||
export default function Alert({ preview }) {
|
||||
return (
|
||||
<div
|
||||
className={cn('border-b', {
|
||||
'bg-accent-7 border-accent-7 text-white': preview,
|
||||
'bg-accent-1 border-accent-2': !preview,
|
||||
})}
|
||||
>
|
||||
<Container>
|
||||
<div className="py-2 text-center text-sm">
|
||||
{preview ? (
|
||||
<>
|
||||
This is page is a preview.{' '}
|
||||
<a
|
||||
href="/api/exit-preview"
|
||||
className="underline hover:text-cyan duration-200 transition-colors"
|
||||
>
|
||||
Click here
|
||||
</a>{' '}
|
||||
to exit preview mode.
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
The source code for this blog is{' '}
|
||||
<a
|
||||
href={`https://github.com/vercel/next.js/tree/canary/examples/${EXAMPLE_PATH}`}
|
||||
className="underline hover:text-success duration-200 transition-colors"
|
||||
>
|
||||
available on GitHub
|
||||
</a>
|
||||
.
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Container>
|
||||
</div>
|
||||
)
|
||||
}
|
17
examples/cms-builder-io/components/avatar.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import BuilderImage from './builder-image'
|
||||
|
||||
export default function Avatar({ name, picture }) {
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
<div className="relative w-12 h-12 mr-4">
|
||||
<BuilderImage
|
||||
src={picture}
|
||||
layout="fill"
|
||||
className="rounded-full"
|
||||
alt={name}
|
||||
/>
|
||||
</div>
|
||||
<div className="text-xl font-bold">{name}</div>
|
||||
</div>
|
||||
)
|
||||
}
|
11
examples/cms-builder-io/components/builder-image.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
import Image from 'next/image'
|
||||
|
||||
const builderLoader = ({ src, width, quality }) => {
|
||||
return `${src}?width=${width}&quality=${quality || 75}`
|
||||
}
|
||||
|
||||
const BuilderImage = (props) => {
|
||||
return <Image loader={builderLoader} {...props} />
|
||||
}
|
||||
|
||||
export default BuilderImage
|
3
examples/cms-builder-io/components/container.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default function Container({ children }) {
|
||||
return <div className="container mx-auto px-5">{children}</div>
|
||||
}
|
29
examples/cms-builder-io/components/cover-image.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
import BuilderImage from './builder-image'
|
||||
import Link from 'next/link'
|
||||
import cn from 'classnames'
|
||||
|
||||
export default function CoverImage({ title, url, slug }) {
|
||||
const image = (
|
||||
<BuilderImage
|
||||
width={2000}
|
||||
height={1000}
|
||||
alt={`Cover Image for ${title}`}
|
||||
className={cn('shadow-small', {
|
||||
'hover:shadow-medium transition-shadow duration-200': slug,
|
||||
})}
|
||||
src={url}
|
||||
/>
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="sm:mx-0">
|
||||
{slug ? (
|
||||
<Link href={`/posts/${slug}`}>
|
||||
<a aria-label={title}>{image}</a>
|
||||
</Link>
|
||||
) : (
|
||||
image
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
9
examples/cms-builder-io/components/date.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { format } from 'date-fns'
|
||||
|
||||
export default function DateComponent({ dateString }) {
|
||||
return (
|
||||
<time dateTime={new Date(dateString)}>
|
||||
{format(new Date(dateString), 'LLLL d, yyyy')}
|
||||
</time>
|
||||
)
|
||||
}
|
30
examples/cms-builder-io/components/footer.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
import Container from './container'
|
||||
import { EXAMPLE_PATH } from '../lib/constants'
|
||||
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer className="bg-accent-1 border-t border-accent-2">
|
||||
<Container>
|
||||
<div className="py-28 flex flex-col lg:flex-row items-center">
|
||||
<h3 className="text-4xl lg:text-5xl font-bold tracking-tighter leading-tight text-center lg:text-left mb-10 lg:mb-0 lg:pr-4 lg:w-1/2">
|
||||
Statically Generated with Next.js.
|
||||
</h3>
|
||||
<div className="flex flex-col lg:flex-row justify-center items-center lg:pl-4 lg:w-1/2">
|
||||
<a
|
||||
href="https://nextjs.org/docs/basic-features/pages"
|
||||
className="mx-3 bg-black hover:bg-white hover:text-black border border-black text-white font-bold py-3 px-12 lg:px-8 duration-200 transition-colors mb-6 lg:mb-0"
|
||||
>
|
||||
Read Documentation
|
||||
</a>
|
||||
<a
|
||||
href={`https://github.com/vercel/next.js/tree/canary/examples/${EXAMPLE_PATH}`}
|
||||
className="mx-3 font-bold hover:underline"
|
||||
>
|
||||
View on GitHub
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
</footer>
|
||||
)
|
||||
}
|
12
examples/cms-builder-io/components/header.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
import Link from 'next/link'
|
||||
|
||||
export default function Header() {
|
||||
return (
|
||||
<h2 className="text-2xl md:text-4xl font-bold tracking-tight md:tracking-tighter leading-tight mb-20 mt-8">
|
||||
<Link href="/">
|
||||
<a className="hover:underline">Blog</a>
|
||||
</Link>
|
||||
.
|
||||
</h2>
|
||||
)
|
||||
}
|
37
examples/cms-builder-io/components/hero-post.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
import Link from 'next/link'
|
||||
import Avatar from '../components/avatar'
|
||||
import DateComponent from '../components/date'
|
||||
import CoverImage from '../components/cover-image'
|
||||
|
||||
export default function HeroPost({
|
||||
title,
|
||||
coverImage,
|
||||
date,
|
||||
excerpt,
|
||||
author,
|
||||
slug,
|
||||
}) {
|
||||
return (
|
||||
<section>
|
||||
<div className="mb-8 md:mb-16">
|
||||
<CoverImage title={title} slug={slug} url={coverImage} />
|
||||
</div>
|
||||
<div className="md:grid md:grid-cols-2 md:col-gap-16 lg:col-gap-8 mb-20 md:mb-28">
|
||||
<div>
|
||||
<h3 className="mb-4 text-4xl lg:text-6xl leading-tight">
|
||||
<Link href={`/posts/${slug}`}>
|
||||
<a className="hover:underline">{title}</a>
|
||||
</Link>
|
||||
</h3>
|
||||
<div className="mb-4 md:mb-0 text-lg">
|
||||
<DateComponent dateString={date} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-lg leading-relaxed mb-4">{excerpt}</p>
|
||||
{author && <Avatar name={author.name} picture={author.image} />}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
28
examples/cms-builder-io/components/intro.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
import { CMS_NAME, CMS_URL } from '../lib/constants'
|
||||
|
||||
export default function Intro() {
|
||||
return (
|
||||
<section className="flex-col md:flex-row flex items-center md:justify-between mt-16 mb-16 md:mb-12">
|
||||
<h1 className="text-6xl md:text-8xl font-bold tracking-tighter leading-tight md:pr-8">
|
||||
Blog.
|
||||
</h1>
|
||||
<h4 className="text-center md:text-left text-lg mt-5 md:pl-8">
|
||||
A statically generated blog example using{' '}
|
||||
<a
|
||||
href="https://nextjs.org/"
|
||||
className="underline hover:text-success duration-200 transition-colors"
|
||||
>
|
||||
Next.js
|
||||
</a>{' '}
|
||||
and{' '}
|
||||
<a
|
||||
href={CMS_URL}
|
||||
className="underline hover:text-success duration-200 transition-colors"
|
||||
>
|
||||
{CMS_NAME}
|
||||
</a>
|
||||
.
|
||||
</h4>
|
||||
</section>
|
||||
)
|
||||
}
|
16
examples/cms-builder-io/components/layout.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import Alert from '../components/alert'
|
||||
import Footer from '../components/footer'
|
||||
import Meta from '../components/meta'
|
||||
|
||||
export default function Layout({ preview, children }) {
|
||||
return (
|
||||
<>
|
||||
<Meta />
|
||||
<div className="min-h-screen">
|
||||
<Alert preview={preview} />
|
||||
<main>{children}</main>
|
||||
</div>
|
||||
<Footer />
|
||||
</>
|
||||
)
|
||||
}
|
42
examples/cms-builder-io/components/meta.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
import Head from 'next/head'
|
||||
import { CMS_NAME, HOME_OG_IMAGE_URL } from '../lib/constants'
|
||||
|
||||
export default function Meta() {
|
||||
return (
|
||||
<Head>
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
href="/favicon/apple-touch-icon.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="32x32"
|
||||
href="/favicon/favicon-32x32.png"
|
||||
/>
|
||||
<link
|
||||
rel="icon"
|
||||
type="image/png"
|
||||
sizes="16x16"
|
||||
href="/favicon/favicon-16x16.png"
|
||||
/>
|
||||
<link rel="manifest" href="/favicon/site.webmanifest" />
|
||||
<link
|
||||
rel="mask-icon"
|
||||
href="/favicon/safari-pinned-tab.svg"
|
||||
color="#000000"
|
||||
/>
|
||||
<link rel="shortcut icon" href="/favicon/favicon.ico" />
|
||||
<meta name="msapplication-TileColor" content="#000000" />
|
||||
<meta name="msapplication-config" content="/favicon/browserconfig.xml" />
|
||||
<meta name="theme-color" content="#000" />
|
||||
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
|
||||
<meta
|
||||
name="description"
|
||||
content={`A statically generated blog example using Next.js and ${CMS_NAME}.`}
|
||||
/>
|
||||
<meta property="og:image" content={HOME_OG_IMAGE_URL} />
|
||||
</Head>
|
||||
)
|
||||
}
|
24
examples/cms-builder-io/components/more-stories.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import PostPreview from './post-preview'
|
||||
|
||||
export default function MoreStories({ posts }) {
|
||||
return (
|
||||
<section>
|
||||
<h2 className="mb-8 text-6xl md:text-7xl font-bold tracking-tighter leading-tight">
|
||||
More Stories
|
||||
</h2>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 md:col-gap-16 lg:col-gap-32 row-gap-20 md:row-gap-32 mb-32">
|
||||
{posts.map((post) => (
|
||||
<PostPreview
|
||||
key={post.data.slug}
|
||||
title={post.data.title}
|
||||
coverImage={post.data.image}
|
||||
date={post.lastUpdated}
|
||||
author={post.data.author.value?.data}
|
||||
slug={post.data.slug}
|
||||
excerpt={post.data.intro}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
13
examples/cms-builder-io/components/post-body.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import { BUILDER_CONFIG } from '@/lib/constants'
|
||||
import { BuilderComponent } from '@builder.io/react'
|
||||
export default function PostBody({ content }) {
|
||||
return (
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<BuilderComponent
|
||||
options={{ includeRefs: true }}
|
||||
model={BUILDER_CONFIG.postsModel}
|
||||
content={content}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
26
examples/cms-builder-io/components/post-header.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
import Avatar from '../components/avatar'
|
||||
import DateComponent from '../components/date'
|
||||
import CoverImage from '../components/cover-image'
|
||||
import PostTitle from '../components/post-title'
|
||||
|
||||
export default function PostHeader({ title, coverImage, date, author }) {
|
||||
return (
|
||||
<>
|
||||
<PostTitle>{title}</PostTitle>
|
||||
<div className="hidden md:block md:mb-12">
|
||||
{author && <Avatar name={author.name} picture={author.image} />}
|
||||
</div>
|
||||
<div className="mb-8 md:mb-16 sm:mx-0">
|
||||
<CoverImage title={title} url={coverImage} />
|
||||
</div>
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<div className="block md:hidden mb-6">
|
||||
{author && <Avatar name={author.name} picture={author.image} />}
|
||||
</div>
|
||||
<div className="mb-6 text-lg">
|
||||
<DateComponent dateString={date} />
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
31
examples/cms-builder-io/components/post-preview.js
Normal file
|
@ -0,0 +1,31 @@
|
|||
import Link from 'next/link'
|
||||
import Avatar from '../components/avatar'
|
||||
import DateComponent from '../components/date'
|
||||
import CoverImage from './cover-image'
|
||||
|
||||
export default function PostPreview({
|
||||
title,
|
||||
coverImage,
|
||||
date,
|
||||
excerpt,
|
||||
author,
|
||||
slug,
|
||||
}) {
|
||||
return (
|
||||
<div className="mx-3">
|
||||
<div className="mb-5">
|
||||
<CoverImage title={title} slug={slug} url={coverImage} />
|
||||
</div>
|
||||
<h3 className="text-3xl mb-3 leading-snug">
|
||||
<Link href={`/posts/${slug}`}>
|
||||
<a className="hover:underline">{title}</a>
|
||||
</Link>
|
||||
</h3>
|
||||
<div className="text-lg mb-4">
|
||||
<DateComponent dateString={date} />
|
||||
</div>
|
||||
<p className="text-lg leading-relaxed mb-4">{excerpt}</p>
|
||||
{author && <Avatar name={author.name} picture={author.image} />}
|
||||
</div>
|
||||
)
|
||||
}
|
7
examples/cms-builder-io/components/post-title.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
export default function PostTitle({ children }) {
|
||||
return (
|
||||
<h1 className="text-6xl md:text-7xl lg:text-8xl font-bold tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left">
|
||||
{children}
|
||||
</h1>
|
||||
)
|
||||
}
|
3
examples/cms-builder-io/components/section-separator.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
export default function SectionSeparator() {
|
||||
return <hr className="border-accent-2 mt-28 mb-24" />
|
||||
}
|
10
examples/cms-builder-io/jsconfig.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/components/*": ["components/*"],
|
||||
"@/lib/*": ["lib/*"],
|
||||
"@/styles/*": ["styles/*"]
|
||||
}
|
||||
}
|
||||
}
|
94
examples/cms-builder-io/lib/api.js
Normal file
|
@ -0,0 +1,94 @@
|
|||
import { Builder, builder } from '@builder.io/react'
|
||||
import { BUILDER_CONFIG } from './constants'
|
||||
|
||||
builder.init(BUILDER_CONFIG.apiKey)
|
||||
Builder.isStatic = true
|
||||
|
||||
export function getAllPostsWithSlug() {
|
||||
return builder.getAll(BUILDER_CONFIG.postsModel, {
|
||||
options: { noTargeting: true },
|
||||
apiKey: BUILDER_CONFIG.apiKey,
|
||||
})
|
||||
}
|
||||
|
||||
export function getAllPostsForHome(preview) {
|
||||
return searchPosts(
|
||||
{ 'data.slug': { $exists: true }, 'data.author': { $exists: true } },
|
||||
preview
|
||||
)
|
||||
}
|
||||
|
||||
export function getDraftPost(id) {
|
||||
return fetch(
|
||||
`https://builder.io/api/v2/content/${BUILDER_CONFIG.postsModel}/${id}?apiKey=${BUILDER_CONFIG.apiKey}&preview=true&noCache=true&cachebust=tru&includeRefs=true`
|
||||
)
|
||||
.then((res) => res.json())
|
||||
.then((res) => res || null)
|
||||
}
|
||||
|
||||
export async function getPost(mongoQuery, preview) {
|
||||
let post = preview
|
||||
? (await searchPosts(mongoQuery, true))?.[0]
|
||||
: await builder
|
||||
.get(BUILDER_CONFIG.postsModel, {
|
||||
includeRefs: true,
|
||||
staleCacheSeconds: 20,
|
||||
apiKey: BUILDER_CONFIG.apiKey,
|
||||
preview: BUILDER_CONFIG.postsModel,
|
||||
options: {
|
||||
noTargeting: true,
|
||||
},
|
||||
query: mongoQuery,
|
||||
})
|
||||
.toPromise()
|
||||
|
||||
return post || null
|
||||
}
|
||||
|
||||
export async function searchPosts(query, preview, limit = 20, offset = 0) {
|
||||
let posts = await builder.getAll(BUILDER_CONFIG.postsModel, {
|
||||
limit,
|
||||
offset,
|
||||
includeRefs: true,
|
||||
preview: BUILDER_CONFIG.postsModel,
|
||||
staleCacheSeconds: preview ? 1 : 200,
|
||||
apiKey: BUILDER_CONFIG.apiKey,
|
||||
...(preview && { includeUnpublished: true }),
|
||||
options: {
|
||||
noTargeting: true,
|
||||
},
|
||||
query,
|
||||
})
|
||||
|
||||
if (preview) {
|
||||
posts = await Promise.all(posts.map((post) => getDraftPost(post.id)))
|
||||
}
|
||||
|
||||
return posts
|
||||
}
|
||||
|
||||
export async function getPostAndMorePosts(slug, preview, previewData) {
|
||||
const post =
|
||||
preview && previewData
|
||||
? await getDraftPost(previewData.postDraftId)
|
||||
: await getPost(
|
||||
{
|
||||
'data.slug': { $eq: slug },
|
||||
},
|
||||
preview
|
||||
)
|
||||
|
||||
const morePosts = await searchPosts(
|
||||
{
|
||||
'data.slug': { $ne: slug, $exists: true },
|
||||
'data.author': { $exists: true },
|
||||
},
|
||||
preview,
|
||||
2
|
||||
)
|
||||
|
||||
return {
|
||||
post,
|
||||
morePosts,
|
||||
}
|
||||
}
|
10
examples/cms-builder-io/lib/constants.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
export const EXAMPLE_PATH = 'cms-builder-io'
|
||||
export const CMS_NAME = 'Builder.io'
|
||||
export const CMS_URL = 'https://builder.io/'
|
||||
export const HOME_OG_IMAGE_URL =
|
||||
'https://og-image.now.sh/Next.js%20Blog%20example%20with%20**Builder.io**.png?theme=light&md=1&fontSize=100px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg&images=https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F79c8b61740bc41d5ae722c000ddb5915'
|
||||
export const BUILDER_CONFIG = {
|
||||
apiKey: process.env.NEXT_PUBLIC_BUILDER_API_KEY,
|
||||
postsModel: 'post',
|
||||
previewSecret: 'micky-mouse',
|
||||
}
|
19
examples/cms-builder-io/next.config.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
module.exports = {
|
||||
images: {
|
||||
domains: ['cdn.builder.io'],
|
||||
},
|
||||
async headers() {
|
||||
return [
|
||||
{
|
||||
source: '/:path*',
|
||||
headers: [
|
||||
{
|
||||
key: 'Content-Security-Policy',
|
||||
value:
|
||||
'frame-ancestors https://*.builder.io https://builder.io http://localhost:1234',
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
},
|
||||
}
|
22
examples/cms-builder-io/package.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@builder.io/react": "^1.1.47",
|
||||
"@builder.io/widgets": "^1.2.21",
|
||||
"classnames": "2.3.1",
|
||||
"date-fns": "2.22.1",
|
||||
"next": "latest",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^10.4.1",
|
||||
"postcss": "^8.4.5",
|
||||
"tailwindcss": "^3.0.11"
|
||||
}
|
||||
}
|
7
examples/cms-builder-io/pages/_app.js
Normal file
|
@ -0,0 +1,7 @@
|
|||
import '@/styles/index.css'
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
return <Component {...pageProps} />
|
||||
}
|
||||
|
||||
export default MyApp
|
8
examples/cms-builder-io/pages/api/exit-preview.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
export default async function exit(_, res) {
|
||||
// Exit the current user from "Preview Mode". This function accepts no args.
|
||||
res.clearPreviewData()
|
||||
|
||||
// Redirect the user back to the index page.
|
||||
res.writeHead(307, { Location: '/' })
|
||||
res.end()
|
||||
}
|
30
examples/cms-builder-io/pages/api/preview.js
Normal file
|
@ -0,0 +1,30 @@
|
|||
import { getDraftPost } from '@/lib/api'
|
||||
import { BUILDER_CONFIG } from '@/lib/constants'
|
||||
import querystring from 'querystring'
|
||||
|
||||
export default async function preview(req, res) {
|
||||
const postId = req.query[`builder.overrides.${BUILDER_CONFIG.postsModel}`]
|
||||
if (req.query.secret !== BUILDER_CONFIG.previewSecret || !postId) {
|
||||
return res.status(401).json({ message: 'Invalid request' })
|
||||
}
|
||||
|
||||
// Check if the post with the given `slug` exists
|
||||
const post = await getDraftPost(postId)
|
||||
|
||||
// If the slug doesn't exist prevent preview mode from being enabled
|
||||
if (!post) {
|
||||
return res.status(401).json({ message: 'Invalid post' })
|
||||
}
|
||||
|
||||
// Enable Preview Mode by setting the cookies
|
||||
res.setPreviewData({
|
||||
postDraftId: postId,
|
||||
})
|
||||
|
||||
// Redirect to the path from the fetched post
|
||||
// We don't redirect to req.query.slug as that might lead to open redirect vulnerabilities
|
||||
res.writeHead(307, {
|
||||
Location: `/posts/${post.data.slug}?${querystring.stringify(req.query)}`,
|
||||
})
|
||||
res.end()
|
||||
}
|
44
examples/cms-builder-io/pages/index.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
import Container from '@/components/container'
|
||||
import MoreStories from '@/components/more-stories'
|
||||
import HeroPost from '@/components/hero-post'
|
||||
import Intro from '@/components/intro'
|
||||
import Layout from '@/components/layout'
|
||||
import { getAllPostsForHome } from '@/lib/api'
|
||||
import Head from 'next/head'
|
||||
import { CMS_NAME } from '@/lib/constants'
|
||||
|
||||
export default function Index({ allPosts, preview }) {
|
||||
const heroPost = allPosts[0]
|
||||
const morePosts = allPosts.slice(1)
|
||||
return (
|
||||
<>
|
||||
<Layout preview={preview}>
|
||||
<Head>
|
||||
<title>Next.js Blog Example with {CMS_NAME}</title>
|
||||
</Head>
|
||||
<Container>
|
||||
<Intro />
|
||||
{heroPost && (
|
||||
<HeroPost
|
||||
title={heroPost.data.title}
|
||||
coverImage={heroPost.data.image}
|
||||
date={heroPost.lastUpdated}
|
||||
author={heroPost.data.author.value?.data}
|
||||
slug={heroPost.data.slug}
|
||||
excerpt={heroPost.data.intro}
|
||||
/>
|
||||
)}
|
||||
{morePosts.length > 0 && <MoreStories posts={morePosts} />}
|
||||
</Container>
|
||||
</Layout>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticProps({ preview = null }) {
|
||||
const allPosts = (await getAllPostsForHome(preview)) || []
|
||||
return {
|
||||
props: { allPosts, preview },
|
||||
revalidate: 20,
|
||||
}
|
||||
}
|
94
examples/cms-builder-io/pages/posts/[slug].js
Normal file
|
@ -0,0 +1,94 @@
|
|||
import { useRouter } from 'next/router'
|
||||
import ErrorPage from 'next/error'
|
||||
import Container from '@/components/container'
|
||||
import PostBody from '@/components/post-body'
|
||||
import MoreStories from '@/components/more-stories'
|
||||
import Header from '@/components/header'
|
||||
import PostHeader from '@/components/post-header'
|
||||
import SectionSeparator from '@/components/section-separator'
|
||||
import Layout from '@/components/layout'
|
||||
import { getAllPostsWithSlug, getPostAndMorePosts } from '@/lib/api'
|
||||
import PostTitle from '@/components/post-title'
|
||||
import Head from 'next/head'
|
||||
import { CMS_NAME, BUILDER_CONFIG } from '@/lib/constants'
|
||||
import { Builder, builder, BuilderContent } from '@builder.io/react'
|
||||
import '@builder.io/widgets'
|
||||
|
||||
builder.init(BUILDER_CONFIG.apiKey)
|
||||
Builder.isStatic = true
|
||||
|
||||
export default function Post({ post, morePosts, preview }) {
|
||||
const router = useRouter()
|
||||
const isLive = !Builder.isEditing && !Builder.isPreviewing && !preview
|
||||
if (!router.isFallback && !post && isLive) {
|
||||
return <ErrorPage statusCode={404} />
|
||||
}
|
||||
return (
|
||||
<Layout preview={preview}>
|
||||
<Container>
|
||||
<Header />
|
||||
{router.isFallback ? (
|
||||
<PostTitle>Loading…</PostTitle>
|
||||
) : (
|
||||
<>
|
||||
<BuilderContent
|
||||
{...(!Builder.isEditing && { content: post })}
|
||||
modelName={BUILDER_CONFIG.postsModel}
|
||||
options={{ includeRefs: true, model: BUILDER_CONFIG.postsModel }}
|
||||
isStatic
|
||||
>
|
||||
{(data) =>
|
||||
data && (
|
||||
<article>
|
||||
<Head>
|
||||
<title>
|
||||
{data.title} | Next.js Blog Example with {CMS_NAME}
|
||||
</title>
|
||||
<meta property="og:image" content={data.image} />
|
||||
</Head>
|
||||
{data.author?.value && (
|
||||
<PostHeader
|
||||
title={data.title}
|
||||
coverImage={data.image}
|
||||
date={post.lastUpdated}
|
||||
author={data.author.value?.data}
|
||||
/>
|
||||
)}
|
||||
<PostBody content={post} />
|
||||
</article>
|
||||
)
|
||||
}
|
||||
</BuilderContent>
|
||||
<SectionSeparator />
|
||||
{morePosts.length > 0 && <MoreStories posts={morePosts} />}
|
||||
</>
|
||||
)}
|
||||
</Container>
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticProps({ params, preview = false, previewData }) {
|
||||
let { post, morePosts } = await getPostAndMorePosts(
|
||||
params.slug,
|
||||
preview,
|
||||
previewData
|
||||
)
|
||||
|
||||
return {
|
||||
props: {
|
||||
key: post?.id + post?.data.slug + params.slug,
|
||||
preview,
|
||||
post,
|
||||
morePosts,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const allPosts = await getAllPostsWithSlug()
|
||||
return {
|
||||
paths: allPosts?.map((post) => `/posts/${post.data.slug}`) || [],
|
||||
fallback: true,
|
||||
}
|
||||
}
|
8
examples/cms-builder-io/postcss.config.js
Normal file
|
@ -0,0 +1,8 @@
|
|||
// If you want to use other PostCSS plugins, see the following:
|
||||
// https://tailwindcss.com/docs/using-with-preprocessors
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 14 KiB |
BIN
examples/cms-builder-io/public/favicon/apple-touch-icon.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
9
examples/cms-builder-io/public/favicon/browserconfig.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/favicons/mstile-150x150.png"/>
|
||||
<TileColor>#000000</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
BIN
examples/cms-builder-io/public/favicon/favicon-16x16.png
Normal file
After Width: | Height: | Size: 595 B |
BIN
examples/cms-builder-io/public/favicon/favicon-32x32.png
Normal file
After Width: | Height: | Size: 880 B |
BIN
examples/cms-builder-io/public/favicon/favicon.ico
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
examples/cms-builder-io/public/favicon/mstile-150x150.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
33
examples/cms-builder-io/public/favicon/safari-pinned-tab.svg
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="1024.000000pt" height="1024.000000pt" viewBox="0 0 1024.000000 1024.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.11, written by Peter Selinger 2001-2013
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,1024.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M4785 10234 c-22 -2 -92 -9 -155 -14 -1453 -131 -2814 -915 -3676
|
||||
-2120 -480 -670 -787 -1430 -903 -2235 -41 -281 -46 -364 -46 -745 0 -381 5
|
||||
-464 46 -745 278 -1921 1645 -3535 3499 -4133 332 -107 682 -180 1080 -224
|
||||
155 -17 825 -17 980 0 687 76 1269 246 1843 539 88 45 105 57 93 67 -8 6 -383
|
||||
509 -833 1117 l-818 1105 -1025 1517 c-564 834 -1028 1516 -1032 1516 -4 1 -8
|
||||
-673 -10 -1496 -3 -1441 -4 -1499 -22 -1533 -26 -49 -46 -69 -88 -91 -32 -16
|
||||
-60 -19 -211 -19 l-173 0 -46 29 c-30 19 -52 44 -67 73 l-21 45 2 2005 3 2006
|
||||
31 39 c16 21 50 48 74 61 41 20 57 22 230 22 204 0 238 -8 291 -66 15 -16 570
|
||||
-852 1234 -1859 664 -1007 1572 -2382 2018 -3057 l810 -1227 41 27 c363 236
|
||||
747 572 1051 922 647 743 1064 1649 1204 2615 41 281 46 364 46 745 0 381 -5
|
||||
464 -46 745 -278 1921 -1645 3535 -3499 4133 -327 106 -675 179 -1065 223 -96
|
||||
10 -757 21 -840 13z m2094 -3094 c48 -24 87 -70 101 -118 8 -26 10 -582 8
|
||||
-1835 l-3 -1798 -317 486 -318 486 0 1307 c0 845 4 1320 10 1343 16 56 51 100
|
||||
99 126 41 21 56 23 213 23 148 0 174 -2 207 -20z"/>
|
||||
<path d="M7843 789 c-35 -22 -46 -37 -15 -20 22 13 58 40 52 41 -3 0 -20 -10
|
||||
-37 -21z"/>
|
||||
<path d="M7774 744 c-18 -14 -18 -15 4 -4 12 6 22 13 22 15 0 8 -5 6 -26 -11z"/>
|
||||
<path d="M7724 714 c-18 -14 -18 -15 4 -4 12 6 22 13 22 15 0 8 -5 6 -26 -11z"/>
|
||||
<path d="M7674 684 c-18 -14 -18 -15 4 -4 12 6 22 13 22 15 0 8 -5 6 -26 -11z"/>
|
||||
<path d="M7598 644 c-38 -20 -36 -28 2 -9 17 9 30 18 30 20 0 7 -1 6 -32 -11z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
19
examples/cms-builder-io/public/favicon/site.webmanifest
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"name": "Next.js",
|
||||
"short_name": "Next.js",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/favicons/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/favicons/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#000000",
|
||||
"display": "standalone"
|
||||
}
|
7
examples/cms-builder-io/styles/index.css
Normal file
|
@ -0,0 +1,7 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
.grayscale {
|
||||
filter: grayscale(1);
|
||||
}
|
36
examples/cms-builder-io/tailwind.config.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
module.exports = {
|
||||
content: ['./components/**/*.js', './pages/**/*.js'],
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: '-apple-system, "Helvetica Neue", "Segoe UI", Roboto, Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',
|
||||
},
|
||||
colors: {
|
||||
'accent-1': '#FAFAFA',
|
||||
'accent-2': '#EAEAEA',
|
||||
'accent-7': '#333',
|
||||
success: '#0070f3',
|
||||
cyan: '#79FFE1',
|
||||
},
|
||||
spacing: {
|
||||
28: '7rem',
|
||||
},
|
||||
letterSpacing: {
|
||||
tighter: '-.04em',
|
||||
},
|
||||
lineHeight: {
|
||||
tight: 1.2,
|
||||
},
|
||||
fontSize: {
|
||||
'5xl': '2.5rem',
|
||||
'6xl': '2.75rem',
|
||||
'7xl': '4.5rem',
|
||||
'8xl': '6.25rem',
|
||||
},
|
||||
boxShadow: {
|
||||
small: '0 5px 10px rgba(0, 0, 0, 0.12)',
|
||||
medium: '0 8px 30px rgba(0, 0, 0, 0.12)',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
|
@ -29,6 +29,7 @@ Once you have access to [the environment variables you'll need](#step-2-set-up-e
|
|||
- [Ghost](/examples/cms-ghost)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ Using the Deploy Button below, you'll deploy the Next.js project as well as conn
|
|||
- [Ghost](/examples/cms-ghost)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e
|
|||
- [Ghost](/examples/cms-ghost)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ This example showcases Next.js's [Static Generation](https://nextjs.org/docs/bas
|
|||
- [Ghost](/examples/cms-ghost)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## Deploy your own
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ Once you have access to [the environment variables you'll need](#step-2-set-up-e
|
|||
- [Kontent](/examples/cms-kontent)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ This example showcases Next.js's [Static Generation](https://nextjs.org/docs/bas
|
|||
- [Ghost](/examples/cms-ghost)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## Deploy your own
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e
|
|||
- [Ghost](/examples/cms-ghost)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ Once you have access to [the environment variables you'll need](#step-5-set-up-e
|
|||
- [Ghost](/examples/cms-ghost)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ Once you have access to [the environment variables you'll need](#step-4-set-up-e
|
|||
- [Ghost](/examples/cms-ghost)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ Once you have access to [the environment variables you'll need](#step-6-set-up-e
|
|||
- [Ghost](/examples/cms-ghost)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ Once you have access to [the environment variables you'll need](#step-7-set-up-e
|
|||
- [Ghost](/examples/cms-ghost)
|
||||
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ Once you have access to [the environment variables you'll need](#step-5-set-up-e
|
|||
- [Kontent](/examples/cms-kontent)
|
||||
- [Ghost](/examples/cms-ghost)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ Once you have access to [the environment variables you'll need](#step-3-set-up-e
|
|||
- [Kontent](/examples/cms-kontent)
|
||||
- [Ghost](/examples/cms-ghost)
|
||||
- [Blog Starter](/examples/blog-starter)
|
||||
- [Builder.io](/examples/cms-builder-io)
|
||||
|
||||
## How to use
|
||||
|
||||
|
|