diff --git a/examples/cms-drupal/.env.local.example b/examples/cms-drupal/.env.local.example
new file mode 100644
index 0000000000000..6f3c4a77a734b
--- /dev/null
+++ b/examples/cms-drupal/.env.local.example
@@ -0,0 +1,6 @@
+NEXT_PUBLIC_DRUPAL_BASE_URL=http://localhost:8080
+NEXT_IMAGE_DOMAIN=localhost
+DRUPAL_SITE_ID=
+DRUPAL_CLIENT_ID=
+DRUPAL_CLIENT_SECRET=
+DRUPAL_PREVIEW_SECRET=
\ No newline at end of file
diff --git a/examples/cms-drupal/.gitignore b/examples/cms-drupal/.gitignore
new file mode 100644
index 0000000000000..1437c53f70bc2
--- /dev/null
+++ b/examples/cms-drupal/.gitignore
@@ -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
diff --git a/examples/cms-drupal/README.md b/examples/cms-drupal/README.md
new file mode 100644
index 0000000000000..7b27e17e005d3
--- /dev/null
+++ b/examples/cms-drupal/README.md
@@ -0,0 +1,51 @@
+# A statically generated blog example using Next.js and Drupal
+
+This example showcases Next.js's [Static Generation](https://nextjs.org/docs/basic-features/pages) feature using [Drupal](https://drupal.org/project/next) as the data source.
+
+## Demo
+
+### [https://cms-drupal.vercel.app](https://cms-drupal.vercel.app)
+
+## Deploy your own
+
+Once you have [configured the Next.js module for Drupal](https://next-drupal.org/guides/decoupled-drupal-nextjs) and have access to the environment variables you'll need, deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
+
+[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/git?c=1&s=https://github.com/vercel/next.js/tree/canary/examples/cms-drupal&env=NEXT_PUBLIC_DRUPAL_BASE_URL,NEXT_IMAGE_DOMAIN,DRUPAL_SITE_ID,DRUPAL_FRONT_PAGE,DRUPAL_PREVIEW_SECRET,DRUPAL_NEXT_CLIENT_ID,DRUPAL_NEXT_CLIENT_SECRET&envDescription=Required%20to%20connect%20the%20app%20with%20ghost&envLink=https://vercel.link/cms-drupal-env)
+
+### 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)
+- [Strapi](/examples/cms-strapi)
+- [Agility CMS](/examples/cms-agilitycms)
+- [Cosmic](/examples/cms-cosmic)
+- [ButterCMS](/examples/cms-buttercms)
+- [Storyblok](/examples/cms-storyblok)
+- [Kontent](/examples/cms-kontent)
+- [Ghost](/examples/cms-ghost)
+- [GraphCMS](/examples/cms-graphcms)
+- [Blog Starter](/examples/blog-starter)
+
+## 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-drupal cms-drupal-app
+# or
+yarn create next-app --example cms-drupal cms-drupal-app
+```
+
+## Setup Drupal
+
+See the Get Started guide [here](https://next-drupal.org/guides/decoupled-drupal-nextjs).
+
+#### 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/import/git?c=1&s=https://github.com/vercel/next.js/tree/canary/examples/cms-drupal&env=NEXT_PUBLIC_DRUPAL_BASE_URL,NEXT_IMAGE_DOMAIN,DRUPAL_SITE_ID,DRUPAL_FRONT_PAGE,DRUPAL_PREVIEW_SECRET,DRUPAL_NEXT_CLIENT_ID,DRUPAL_NEXT_CLIENT_SECRET&envDescription=Required%20to%20connect%20the%20app%20with%20ghost&envLink=https://vercel.link/cms-drupal-env)
diff --git a/examples/cms-drupal/components/alert.js b/examples/cms-drupal/components/alert.js
new file mode 100644
index 0000000000000..b924cb097f169
--- /dev/null
+++ b/examples/cms-drupal/components/alert.js
@@ -0,0 +1,42 @@
+import Container from './container'
+import cn from 'classnames'
+import { EXAMPLE_PATH } from '../lib/constants'
+
+export default function Alert({ preview }) {
+ return (
+
+
+
+ {preview ? (
+ <>
+ This page is a preview.{' '}
+
+ Click here
+ {' '}
+ to exit preview mode.
+ >
+ ) : (
+ <>
+ The source code for this blog is{' '}
+
+ available on GitHub
+
+ .
+ >
+ )}
+
+
+
+ )
+}
diff --git a/examples/cms-drupal/components/avatar.js b/examples/cms-drupal/components/avatar.js
new file mode 100644
index 0000000000000..1921a724634d9
--- /dev/null
+++ b/examples/cms-drupal/components/avatar.js
@@ -0,0 +1,27 @@
+import Image from 'next/image'
+
+export default function Avatar({ author }) {
+ const name = author
+ ? author.firstName && author.lastName
+ ? `${author.firstName} ${author.lastName}`
+ : author.name
+ : null
+
+ return (
+ <>
+ {author && (
+
+ )}
+ >
+ )
+}
diff --git a/examples/cms-drupal/components/categories.js b/examples/cms-drupal/components/categories.js
new file mode 100644
index 0000000000000..0beb1ff5335cc
--- /dev/null
+++ b/examples/cms-drupal/components/categories.js
@@ -0,0 +1,16 @@
+export default function Categories({ categories }) {
+ return (
+
+ under
+ {categories.edges.length > 0 ? (
+ categories.edges.map((category, index) => (
+
+ {category.node.name}
+
+ ))
+ ) : (
+ {categories.edges.node.name}
+ )}
+
+ )
+}
diff --git a/examples/cms-drupal/components/container.js b/examples/cms-drupal/components/container.js
new file mode 100644
index 0000000000000..fc1c29dfb0747
--- /dev/null
+++ b/examples/cms-drupal/components/container.js
@@ -0,0 +1,3 @@
+export default function Container({ children }) {
+ return {children}
+}
diff --git a/examples/cms-drupal/components/cover-image.js b/examples/cms-drupal/components/cover-image.js
new file mode 100644
index 0000000000000..176a870f81f80
--- /dev/null
+++ b/examples/cms-drupal/components/cover-image.js
@@ -0,0 +1,28 @@
+import cn from 'classnames'
+import Image from 'next/image'
+import Link from 'next/link'
+
+export default function CoverImage({ title, coverImage, slug }) {
+ const image = (
+
+ )
+ return (
+
+ {slug ? (
+
+
{image}
+
+ ) : (
+ image
+ )}
+
+ )
+}
diff --git a/examples/cms-drupal/components/date.js b/examples/cms-drupal/components/date.js
new file mode 100644
index 0000000000000..eac5681378bfd
--- /dev/null
+++ b/examples/cms-drupal/components/date.js
@@ -0,0 +1,6 @@
+import { parseISO, format } from 'date-fns'
+
+export default function Date({ dateString }) {
+ const date = parseISO(dateString)
+ return {format(date, 'LLLL d, yyyy')}
+}
diff --git a/examples/cms-drupal/components/footer.js b/examples/cms-drupal/components/footer.js
new file mode 100644
index 0000000000000..da9eed88ec263
--- /dev/null
+++ b/examples/cms-drupal/components/footer.js
@@ -0,0 +1,30 @@
+import Container from './container'
+import { EXAMPLE_PATH } from '../lib/constants'
+
+export default function Footer() {
+ return (
+
+
+
+
+ Statically Generated with Next.js.
+
+
+
+
+
+ )
+}
diff --git a/examples/cms-drupal/components/header.js b/examples/cms-drupal/components/header.js
new file mode 100644
index 0000000000000..562e7e3eebb6a
--- /dev/null
+++ b/examples/cms-drupal/components/header.js
@@ -0,0 +1,12 @@
+import Link from 'next/link'
+
+export default function Header() {
+ return (
+
+
+ Blog
+
+ .
+
+ )
+}
diff --git a/examples/cms-drupal/components/hero-post.js b/examples/cms-drupal/components/hero-post.js
new file mode 100644
index 0000000000000..c5aa6d0a76609
--- /dev/null
+++ b/examples/cms-drupal/components/hero-post.js
@@ -0,0 +1,45 @@
+import Avatar from '../components/avatar'
+import Date from '../components/date'
+import CoverImage from '../components/cover-image'
+import Link from 'next/link'
+
+export default function HeroPost({
+ title,
+ coverImage,
+ date,
+ excerpt,
+ author,
+ slug,
+}) {
+ return (
+
+
+ {coverImage && (
+
+ )}
+
+
+
+ )
+}
diff --git a/examples/cms-drupal/components/intro.js b/examples/cms-drupal/components/intro.js
new file mode 100644
index 0000000000000..5931b3c5961bd
--- /dev/null
+++ b/examples/cms-drupal/components/intro.js
@@ -0,0 +1,28 @@
+import { CMS_NAME, CMS_URL } from '../lib/constants'
+
+export default function Intro() {
+ return (
+
+ )
+}
diff --git a/examples/cms-drupal/components/layout.js b/examples/cms-drupal/components/layout.js
new file mode 100644
index 0000000000000..99d95353131e0
--- /dev/null
+++ b/examples/cms-drupal/components/layout.js
@@ -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 (
+ <>
+
+
+
+ >
+ )
+}
diff --git a/examples/cms-drupal/components/meta.js b/examples/cms-drupal/components/meta.js
new file mode 100644
index 0000000000000..d9c48d5831e13
--- /dev/null
+++ b/examples/cms-drupal/components/meta.js
@@ -0,0 +1,42 @@
+import Head from 'next/head'
+import { CMS_NAME, HOME_OG_IMAGE_URL } from '../lib/constants'
+
+export default function Meta() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/examples/cms-drupal/components/more-stories.js b/examples/cms-drupal/components/more-stories.js
new file mode 100644
index 0000000000000..5ef60e09a1ee3
--- /dev/null
+++ b/examples/cms-drupal/components/more-stories.js
@@ -0,0 +1,32 @@
+import { absoluteURL } from '../lib/api'
+import PostPreview from './post-preview'
+
+export default function MoreStories({ posts }) {
+ return (
+
+
+ More Stories
+
+
+ {posts.map((node) => (
+
+ ))}
+
+
+ )
+}
diff --git a/examples/cms-drupal/components/post-body.js b/examples/cms-drupal/components/post-body.js
new file mode 100644
index 0000000000000..cc3a92b881e24
--- /dev/null
+++ b/examples/cms-drupal/components/post-body.js
@@ -0,0 +1,12 @@
+import styles from './post-body.module.css'
+
+export default function PostBody({ content }) {
+ return (
+
+ )
+}
diff --git a/examples/cms-drupal/components/post-body.module.css b/examples/cms-drupal/components/post-body.module.css
new file mode 100644
index 0000000000000..a6adbe02267c0
--- /dev/null
+++ b/examples/cms-drupal/components/post-body.module.css
@@ -0,0 +1,76 @@
+.content {
+ @apply text-lg leading-relaxed;
+}
+
+.content p,
+.content ul,
+.content ol,
+.content blockquote {
+ @apply my-6;
+}
+
+.content a {
+ @apply underline;
+}
+
+.content ul,
+.content ol {
+ @apply pl-4;
+}
+
+.content ul {
+ @apply list-disc;
+}
+
+.content ol {
+ @apply list-decimal;
+}
+
+.content ul > li > ul,
+.content ol > li > ol {
+ @apply my-0 ml-4;
+}
+
+.content ul > li > ul {
+ list-style: circle;
+}
+
+.content h2 {
+ @apply text-3xl mt-12 mb-4 leading-snug;
+}
+
+.content h3 {
+ @apply text-2xl mt-8 mb-4 leading-snug;
+}
+
+.content h4 {
+ @apply text-xl mt-6 mb-4 leading-snug;
+}
+
+.content pre {
+ @apply whitespace-pre overflow-x-auto p-4 text-sm leading-tight border border-gray-400 bg-gray-100;
+}
+
+.content code {
+ @apply text-sm;
+}
+
+.content figcaption {
+ @apply text-center text-sm;
+}
+
+.content blockquote {
+ @apply border-l-4 border-gray-500 bg-gray-200 italic ml-0 py-4 px-6;
+}
+
+.content blockquote p {
+ @apply mt-0;
+}
+
+.content blockquote cite {
+ @apply not-italic;
+}
+
+.content audio {
+ @apply w-full;
+}
diff --git a/examples/cms-drupal/components/post-header.js b/examples/cms-drupal/components/post-header.js
new file mode 100644
index 0000000000000..df099adb374ba
--- /dev/null
+++ b/examples/cms-drupal/components/post-header.js
@@ -0,0 +1,34 @@
+import Avatar from '../components/avatar'
+import Date from '../components/date'
+import CoverImage from '../components/cover-image'
+import PostTitle from '../components/post-title'
+import Categories from '../components/categories'
+
+export default function PostHeader({
+ title,
+ coverImage,
+ date,
+ author,
+ categories,
+}) {
+ return (
+ <>
+ {title}
+
+
+
+
+
+
+
+ Posted
+ {categories?.length ? : null}
+
+
+ >
+ )
+}
diff --git a/examples/cms-drupal/components/post-preview.js b/examples/cms-drupal/components/post-preview.js
new file mode 100644
index 0000000000000..6496340e64e2c
--- /dev/null
+++ b/examples/cms-drupal/components/post-preview.js
@@ -0,0 +1,37 @@
+import Avatar from '../components/avatar'
+import Date from '../components/date'
+import CoverImage from './cover-image'
+import Link from 'next/link'
+
+export default function PostPreview({
+ title,
+ coverImage,
+ date,
+ excerpt,
+ author,
+ slug,
+}) {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/examples/cms-drupal/components/post-title.js b/examples/cms-drupal/components/post-title.js
new file mode 100644
index 0000000000000..25893a3dd9ff7
--- /dev/null
+++ b/examples/cms-drupal/components/post-title.js
@@ -0,0 +1,8 @@
+export default function PostTitle({ children }) {
+ return (
+
+ )
+}
diff --git a/examples/cms-drupal/components/section-separator.js b/examples/cms-drupal/components/section-separator.js
new file mode 100644
index 0000000000000..4ca5c65fdc6ee
--- /dev/null
+++ b/examples/cms-drupal/components/section-separator.js
@@ -0,0 +1,3 @@
+export default function SectionSeparator() {
+ return
+}
diff --git a/examples/cms-drupal/components/tags.js b/examples/cms-drupal/components/tags.js
new file mode 100644
index 0000000000000..4f5f35ccac45b
--- /dev/null
+++ b/examples/cms-drupal/components/tags.js
@@ -0,0 +1,14 @@
+export default function Tags({ tags }) {
+ return (
+
+
+ Tagged
+ {tags.edges.map((tag, index) => (
+
+ {tag.node.name}
+
+ ))}
+
+
+ )
+}
diff --git a/examples/cms-drupal/lib/api.js b/examples/cms-drupal/lib/api.js
new file mode 100644
index 0000000000000..4b736b1b6570e
--- /dev/null
+++ b/examples/cms-drupal/lib/api.js
@@ -0,0 +1,3 @@
+export function absoluteURL(url) {
+ return `${process.env.NEXT_PUBLIC_DRUPAL_BASE_URL}${url}`
+}
diff --git a/examples/cms-drupal/lib/constants.js b/examples/cms-drupal/lib/constants.js
new file mode 100644
index 0000000000000..c10bd3fa4f104
--- /dev/null
+++ b/examples/cms-drupal/lib/constants.js
@@ -0,0 +1,5 @@
+export const EXAMPLE_PATH = 'cms-drupal'
+export const CMS_NAME = 'Drupal'
+export const CMS_URL = 'https://drupal.org/project/next'
+export const HOME_OG_IMAGE_URL =
+ 'https://og-image.vercel.app/Next.js%20Example%20Blog%20with%20**Drupal**.png?theme=light&md=1&fontSize=75px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg&images=https%3A%2F%2Fwww.drupal.org%2Ffiles%2FEL_blue_RGB%25281%2529.png'
diff --git a/examples/cms-drupal/next.config.js b/examples/cms-drupal/next.config.js
new file mode 100644
index 0000000000000..2940b486cbb59
--- /dev/null
+++ b/examples/cms-drupal/next.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ images: {
+ domains: [process.env.NEXT_IMAGE_DOMAIN],
+ },
+}
diff --git a/examples/cms-drupal/package.json b/examples/cms-drupal/package.json
new file mode 100644
index 0000000000000..e51c36e4dacbb
--- /dev/null
+++ b/examples/cms-drupal/package.json
@@ -0,0 +1,25 @@
+{
+ "name": "cms-drupal",
+ "version": "1.0.0",
+ "scripts": {
+ "dev": "next",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "classnames": "2.3.1",
+ "date-fns": "2.21.3",
+ "next": "latest",
+ "next-drupal": "latest",
+ "react": "17.0.2",
+ "react-dom": "17.0.2"
+ },
+ "devDependencies": {
+ "autoprefixer": "10.2.5",
+ "postcss": "8.2.15",
+ "postcss-flexbugs-fixes": "5.0.2",
+ "postcss-preset-env": "6.7.0",
+ "tailwindcss": "2.1.2"
+ },
+ "license": "MIT"
+}
diff --git a/examples/cms-drupal/pages/[...slug].js b/examples/cms-drupal/pages/[...slug].js
new file mode 100644
index 0000000000000..924efa292eb30
--- /dev/null
+++ b/examples/cms-drupal/pages/[...slug].js
@@ -0,0 +1,107 @@
+import { useRouter } from 'next/router'
+import ErrorPage from 'next/error'
+import Head from 'next/head'
+import {
+ getPathsFromContext,
+ getResourceCollectionFromContext,
+ getResourceFromContext,
+} from 'next-drupal'
+
+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 PostTitle from '../components/post-title'
+
+import { CMS_NAME } from '../lib/constants'
+import { absoluteURL } from '../lib/api'
+
+export default function Post({ post, morePosts, preview }) {
+ const router = useRouter()
+ if (!router.isFallback && !post?.id) {
+ return
+ }
+ return (
+
+
+
+ {router.isFallback ? (
+ Loading…
+ ) : (
+ <>
+
+
+
+ {post.title} | Next.js Blog Example with {CMS_NAME}
+
+
+
+
+
+
+
+ {morePosts.length > 0 && }
+ >
+ )}
+
+
+ )
+}
+
+export async function getStaticProps(context) {
+ const post = await getResourceFromContext('node--article', context, {
+ params: {
+ include: 'field_image,uid,uid.user_picture',
+ },
+ })
+
+ let morePosts = []
+ if (post) {
+ morePosts = await getResourceCollectionFromContext(
+ 'node--article',
+ context,
+ {
+ params: {
+ include: 'field_image,uid,uid.user_picture',
+ sort: '-created',
+ 'filter[id][condition][path]': 'id',
+ 'filter[id][condition][operator]': '<>',
+ 'filter[id][condition][value]': post.id,
+ },
+ }
+ )
+ }
+
+ return {
+ props: {
+ preview: context.preview || false,
+ post,
+ morePosts,
+ },
+ }
+}
+
+export async function getStaticPaths(context) {
+ return {
+ paths: await getPathsFromContext('node--article', context),
+ fallback: true,
+ }
+}
diff --git a/examples/cms-drupal/pages/_app.js b/examples/cms-drupal/pages/_app.js
new file mode 100644
index 0000000000000..d56d9bf601a90
--- /dev/null
+++ b/examples/cms-drupal/pages/_app.js
@@ -0,0 +1,7 @@
+import '../styles/index.css'
+
+function MyApp({ Component, pageProps }) {
+ return
+}
+
+export default MyApp
diff --git a/examples/cms-drupal/pages/_document.js b/examples/cms-drupal/pages/_document.js
new file mode 100644
index 0000000000000..c55951c0d5daf
--- /dev/null
+++ b/examples/cms-drupal/pages/_document.js
@@ -0,0 +1,15 @@
+import Document, { Html, Head, Main, NextScript } from 'next/document'
+
+export default class MyDocument extends Document {
+ render() {
+ return (
+
+
+
+
+
+
+ )
+ }
+}
diff --git a/examples/cms-drupal/pages/api/exit-preview.js b/examples/cms-drupal/pages/api/exit-preview.js
new file mode 100644
index 0000000000000..6c63a0a6e8a42
--- /dev/null
+++ b/examples/cms-drupal/pages/api/exit-preview.js
@@ -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()
+}
diff --git a/examples/cms-drupal/pages/api/preview.js b/examples/cms-drupal/pages/api/preview.js
new file mode 100644
index 0000000000000..39fa2fca4d71e
--- /dev/null
+++ b/examples/cms-drupal/pages/api/preview.js
@@ -0,0 +1,3 @@
+import { DrupalPreview } from 'next-drupal'
+
+export default DrupalPreview()
diff --git a/examples/cms-drupal/pages/index.js b/examples/cms-drupal/pages/index.js
new file mode 100644
index 0000000000000..5b884d7afb48a
--- /dev/null
+++ b/examples/cms-drupal/pages/index.js
@@ -0,0 +1,60 @@
+import Head from 'next/head'
+import { getResourceCollectionFromContext } from 'next-drupal'
+
+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 { CMS_NAME } from '../lib/constants'
+import { absoluteURL } from '../lib/api'
+
+export default function Index({ posts }) {
+ const heroPost = posts[0]
+ const morePosts = posts.slice(1)
+ return (
+
+
+ Next.js Blog Example with {CMS_NAME}
+
+
+
+ {heroPost && (
+
+ )}
+ {morePosts.length > 0 && }
+
+
+ )
+}
+
+export async function getStaticProps(context) {
+ const posts = await getResourceCollectionFromContext(
+ 'node--article',
+ context,
+ {
+ params: {
+ include: 'field_image,uid,uid.user_picture',
+ sort: '-created',
+ },
+ }
+ )
+
+ return {
+ props: { posts },
+ }
+}
diff --git a/examples/cms-drupal/postcss.config.js b/examples/cms-drupal/postcss.config.js
new file mode 100644
index 0000000000000..6f2d25c4e3509
--- /dev/null
+++ b/examples/cms-drupal/postcss.config.js
@@ -0,0 +1,18 @@
+module.exports = {
+ plugins: [
+ 'tailwindcss',
+ 'postcss-flexbugs-fixes',
+ [
+ 'postcss-preset-env',
+ {
+ autoprefixer: {
+ flexbox: 'no-2009',
+ },
+ stage: 3,
+ features: {
+ 'custom-properties': false,
+ },
+ },
+ ],
+ ],
+}
diff --git a/examples/cms-drupal/public/favicon/android-chrome-192x192.png b/examples/cms-drupal/public/favicon/android-chrome-192x192.png
new file mode 100644
index 0000000000000..2f07282a59cda
Binary files /dev/null and b/examples/cms-drupal/public/favicon/android-chrome-192x192.png differ
diff --git a/examples/cms-drupal/public/favicon/android-chrome-512x512.png b/examples/cms-drupal/public/favicon/android-chrome-512x512.png
new file mode 100644
index 0000000000000..dbb0faea84049
Binary files /dev/null and b/examples/cms-drupal/public/favicon/android-chrome-512x512.png differ
diff --git a/examples/cms-drupal/public/favicon/apple-touch-icon.png b/examples/cms-drupal/public/favicon/apple-touch-icon.png
new file mode 100644
index 0000000000000..8f4033b2a8b35
Binary files /dev/null and b/examples/cms-drupal/public/favicon/apple-touch-icon.png differ
diff --git a/examples/cms-drupal/public/favicon/browserconfig.xml b/examples/cms-drupal/public/favicon/browserconfig.xml
new file mode 100644
index 0000000000000..9824d87b11517
--- /dev/null
+++ b/examples/cms-drupal/public/favicon/browserconfig.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+ #000000
+
+
+
diff --git a/examples/cms-drupal/public/favicon/favicon-16x16.png b/examples/cms-drupal/public/favicon/favicon-16x16.png
new file mode 100644
index 0000000000000..29deaf6716e77
Binary files /dev/null and b/examples/cms-drupal/public/favicon/favicon-16x16.png differ
diff --git a/examples/cms-drupal/public/favicon/favicon-32x32.png b/examples/cms-drupal/public/favicon/favicon-32x32.png
new file mode 100644
index 0000000000000..e3b4277bf093d
Binary files /dev/null and b/examples/cms-drupal/public/favicon/favicon-32x32.png differ
diff --git a/examples/cms-drupal/public/favicon/favicon.ico b/examples/cms-drupal/public/favicon/favicon.ico
new file mode 100644
index 0000000000000..ea2f437d9db65
Binary files /dev/null and b/examples/cms-drupal/public/favicon/favicon.ico differ
diff --git a/examples/cms-drupal/public/favicon/mstile-150x150.png b/examples/cms-drupal/public/favicon/mstile-150x150.png
new file mode 100644
index 0000000000000..f2dfd904bf1be
Binary files /dev/null and b/examples/cms-drupal/public/favicon/mstile-150x150.png differ
diff --git a/examples/cms-drupal/public/favicon/safari-pinned-tab.svg b/examples/cms-drupal/public/favicon/safari-pinned-tab.svg
new file mode 100644
index 0000000000000..72ab6e050cb11
--- /dev/null
+++ b/examples/cms-drupal/public/favicon/safari-pinned-tab.svg
@@ -0,0 +1,33 @@
+
+
+
+
+Created by potrace 1.11, written by Peter Selinger 2001-2013
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/cms-drupal/public/favicon/site.webmanifest b/examples/cms-drupal/public/favicon/site.webmanifest
new file mode 100644
index 0000000000000..a672d9a233c59
--- /dev/null
+++ b/examples/cms-drupal/public/favicon/site.webmanifest
@@ -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"
+}
diff --git a/examples/cms-drupal/styles/index.css b/examples/cms-drupal/styles/index.css
new file mode 100644
index 0000000000000..a9e25784dbea9
--- /dev/null
+++ b/examples/cms-drupal/styles/index.css
@@ -0,0 +1,7 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+.container {
+ max-width: 1280px;
+}
diff --git a/examples/cms-drupal/tailwind.config.js b/examples/cms-drupal/tailwind.config.js
new file mode 100644
index 0000000000000..3ce26bd0cdab1
--- /dev/null
+++ b/examples/cms-drupal/tailwind.config.js
@@ -0,0 +1,34 @@
+module.exports = {
+ mode: 'jit',
+ purge: ['./components/**/*.js', './pages/**/*.js'],
+ theme: {
+ extend: {
+ 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)',
+ },
+ },
+ },
+}