diff --git a/examples/cms-sitefinity/.env.local.example b/examples/cms-sitefinity/.env.local.example
new file mode 100644
index 0000000000000..bc91dbf222f84
--- /dev/null
+++ b/examples/cms-sitefinity/.env.local.example
@@ -0,0 +1,2 @@
+SF_API_URL=
+SF_URL=
diff --git a/examples/cms-sitefinity/.gitignore b/examples/cms-sitefinity/.gitignore
new file mode 100644
index 0000000000000..c87c9b392c020
--- /dev/null
+++ b/examples/cms-sitefinity/.gitignore
@@ -0,0 +1,36 @@
+# 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*
+.pnpm-debug.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
diff --git a/examples/cms-sitefinity/README.md b/examples/cms-sitefinity/README.md
new file mode 100644
index 0000000000000..9d0333d9fb9dd
--- /dev/null
+++ b/examples/cms-sitefinity/README.md
@@ -0,0 +1,103 @@
+# A statically generated blog example using Next.js and Sitefinity CMS
+
+This is the existing [cms-sitefinity](https://github.com/vercel/next.js/tree/canary/examples/cms-sitefinity) plus TypeScript.
+This example showcases [Next.js's Static Generation feature](https://nextjs.org/docs/basic-features/pages) using Sitefinity CMS as the data source.
+
+## Demo
+
+[https://next-cms-sitefinity.vercel.app/](https://next-cms-sitefinity.vercel.app/)
+
+## Deploy your own
+
+Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/cms-sitefinity)
+
+[![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-sitefinity&project-name=cms-sitefinity&repository-name=cms-sitefinity)
+
+### 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)
+- [GraphCMS](/examples/cms-graphcms)
+- [Kontent](/examples/cms-kontent)
+- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
+- [Builder.io](/examples/cms-builder-io)
+- [TinaCMS](/examples/cms-tina/)
+
+## 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), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example:
+
+```bash
+npx create-next-app --example cms-sitefinity cms-sitefinity-app
+```
+
+```bash
+yarn create next-app --example cms-sitefinity cms-sitefinity-app
+```
+
+```bash
+pnpm create next-app --example cms-sitefinity cms-sitefinity-app
+```
+
+## Configuration
+
+### Step 1. Setup the CMS locally (version >=14.27922)
+
+First, [install](https://www.progress.com/documentation/sitefinity-cms/install-sitefinity) and run the CMS Locally.
+
+### Step 2. Import the ready to use dynamic module 'Posts'
+
+For the purpose of this demo a ready to use dynamic module was build containing two types - 'Post' and 'Author'.
+
+In order to install it:
+
+1. Open the CMS Administration under (/Sitefinity)
+2. Open the Export/Import screen under (/Sitefinity/Administration/Packaging)
+3. Click on Import Zip file and import the file from the [sitefinity folder](./sitefinity/SitefinityExport.zip)
+
+### Step 3. Enable the web service
+
+By default the web services are not allowed for anonymous users, so the yhave to be enabled.
+
+Go to /sitefinity/Administration/WebServices and edit the 'Default' web service to allow it to be accessible by 'Everyone'
+
+### Step 4. Install the GraphQL package
+
+1. Add the [Sitefinity CMS nugget source](https://www.progress.com/documentation/sitefinity-cms/sitefinity-cms-nuget-packages-repository)
+2. Install the [Progress.Sitefinity.GraphQL](https://nuget.sitefinity.com/#/package/Progress.Sitefinity.GraphQL) package (enable prerelease filter).
+
+### Step 5. Set up environment variables
+
+Copy the `.env.local.example` file in this directory to `.env.local` (which will be ignored by Git):
+
+```bash
+cp .env.local.example .env.local
+```
+
+Then set each variable on `.env.local`
+
+- `SF_API_URL` - This is the url of the 'Default' web service that we configured earlier. E.g. http://locahost/api/default/
+- `SF_URL` - This is the URL of the CMS itself. E.g. http://localhost/
+
+### Step 6. Run Next.js in development mode
+
+```bash
+npm install
+npm run dev
+
+# or
+
+yarn
+yarn dev
+```
+
+Your blog should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions).
diff --git a/examples/cms-sitefinity/components/alert.tsx b/examples/cms-sitefinity/components/alert.tsx
new file mode 100644
index 0000000000000..067672f380826
--- /dev/null
+++ b/examples/cms-sitefinity/components/alert.tsx
@@ -0,0 +1,48 @@
+import Container from './container'
+import cn from 'classnames'
+import { EXAMPLE_PATH } from '../lib/constants'
+
+type Props = {
+ preview?: boolean
+}
+
+const Alert = ({ preview }: Props) => {
+ return (
+
+
+
+ {preview ? (
+ <>
+ This page is a preview.{' '}
+
+ Click here
+ {' '}
+ to exit preview mode.
+ >
+ ) : (
+ <>
+ The source code for this blog is{' '}
+
+ available on GitHub
+
+ .
+ >
+ )}
+
+
+
+ )
+}
+
+export default Alert
diff --git a/examples/cms-sitefinity/components/avatar.tsx b/examples/cms-sitefinity/components/avatar.tsx
new file mode 100644
index 0000000000000..920d385162244
--- /dev/null
+++ b/examples/cms-sitefinity/components/avatar.tsx
@@ -0,0 +1,15 @@
+type Props = {
+ name: string
+ picture: string
+}
+
+const Avatar = ({ name, picture }: Props) => {
+ return (
+
+
+
{name}
+
+ )
+}
+
+export default Avatar
diff --git a/examples/cms-sitefinity/components/container.tsx b/examples/cms-sitefinity/components/container.tsx
new file mode 100644
index 0000000000000..1a1f68714480c
--- /dev/null
+++ b/examples/cms-sitefinity/components/container.tsx
@@ -0,0 +1,9 @@
+type Props = {
+ children?: React.ReactNode
+}
+
+const Container = ({ children }: Props) => {
+ return {children}
+}
+
+export default Container
diff --git a/examples/cms-sitefinity/components/cover-image.tsx b/examples/cms-sitefinity/components/cover-image.tsx
new file mode 100644
index 0000000000000..1541fddb6b964
--- /dev/null
+++ b/examples/cms-sitefinity/components/cover-image.tsx
@@ -0,0 +1,33 @@
+import cn from 'classnames'
+import Link from 'next/link'
+
+type Props = {
+ title: string
+ src: string
+ slug?: string
+}
+
+const CoverImage = ({ title, src, slug }: Props) => {
+ const image = (
+
+ )
+ return (
+
+ {slug ? (
+
+
{image}
+
+ ) : (
+ image
+ )}
+
+ )
+}
+
+export default CoverImage
diff --git a/examples/cms-sitefinity/components/date-formatter.tsx b/examples/cms-sitefinity/components/date-formatter.tsx
new file mode 100644
index 0000000000000..e827be5e9c84d
--- /dev/null
+++ b/examples/cms-sitefinity/components/date-formatter.tsx
@@ -0,0 +1,12 @@
+import { parseISO, format } from 'date-fns'
+
+type Props = {
+ dateString: string
+}
+
+const DateFormatter = ({ dateString }: Props) => {
+ const date = parseISO(dateString)
+ return {format(date, 'LLLL d, yyyy')}
+}
+
+export default DateFormatter
diff --git a/examples/cms-sitefinity/components/footer.tsx b/examples/cms-sitefinity/components/footer.tsx
new file mode 100644
index 0000000000000..d2bcba33363b6
--- /dev/null
+++ b/examples/cms-sitefinity/components/footer.tsx
@@ -0,0 +1,32 @@
+import Container from './container'
+import { EXAMPLE_PATH } from '../lib/constants'
+
+const Footer = () => {
+ return (
+
+
+
+
+ Statically Generated with Next.js.
+
+
+
+
+
+ )
+}
+
+export default Footer
diff --git a/examples/cms-sitefinity/components/header.tsx b/examples/cms-sitefinity/components/header.tsx
new file mode 100644
index 0000000000000..4b516c600c985
--- /dev/null
+++ b/examples/cms-sitefinity/components/header.tsx
@@ -0,0 +1,14 @@
+import Link from 'next/link'
+
+const Header = () => {
+ return (
+
+
+ Blog
+
+ .
+
+ )
+}
+
+export default Header
diff --git a/examples/cms-sitefinity/components/hero-post.tsx b/examples/cms-sitefinity/components/hero-post.tsx
new file mode 100644
index 0000000000000..ac628526c1924
--- /dev/null
+++ b/examples/cms-sitefinity/components/hero-post.tsx
@@ -0,0 +1,49 @@
+import Avatar from './avatar'
+import DateFormatter from './date-formatter'
+import CoverImage from './cover-image'
+import Link from 'next/link'
+import type Author from '../interfaces/author'
+
+type Props = {
+ title: string
+ coverImage: string
+ date: string
+ excerpt: string
+ author: Author
+ slug: string
+}
+
+const HeroPost = ({
+ title,
+ coverImage,
+ date,
+ excerpt,
+ author,
+ slug,
+}: Props) => {
+ return (
+
+ )
+}
+
+export default HeroPost
diff --git a/examples/cms-sitefinity/components/intro.tsx b/examples/cms-sitefinity/components/intro.tsx
new file mode 100644
index 0000000000000..d41e6fb1b994d
--- /dev/null
+++ b/examples/cms-sitefinity/components/intro.tsx
@@ -0,0 +1,23 @@
+import { CMS_NAME } from '../lib/constants'
+
+const Intro = () => {
+ return (
+
+
+ Blog.
+
+
+ A statically generated blog example using{' '}
+
+ Next.js
+ {' '}
+ and {CMS_NAME}.
+
+
+ )
+}
+
+export default Intro
diff --git a/examples/cms-sitefinity/components/layout.tsx b/examples/cms-sitefinity/components/layout.tsx
new file mode 100644
index 0000000000000..9cd23e56e1499
--- /dev/null
+++ b/examples/cms-sitefinity/components/layout.tsx
@@ -0,0 +1,23 @@
+import Alert from './alert'
+import Footer from './footer'
+import Meta from './meta'
+
+type Props = {
+ preview?: boolean
+ children: React.ReactNode
+}
+
+const Layout = ({ preview, children }: Props) => {
+ return (
+ <>
+
+
+
+ >
+ )
+}
+
+export default Layout
diff --git a/examples/cms-sitefinity/components/markdown-styles.module.css b/examples/cms-sitefinity/components/markdown-styles.module.css
new file mode 100644
index 0000000000000..95d4f8b04172d
--- /dev/null
+++ b/examples/cms-sitefinity/components/markdown-styles.module.css
@@ -0,0 +1,18 @@
+.markdown {
+ @apply text-lg leading-relaxed;
+}
+
+.markdown p,
+.markdown ul,
+.markdown ol,
+.markdown blockquote {
+ @apply my-6;
+}
+
+.markdown h2 {
+ @apply text-3xl mt-12 mb-4 leading-snug;
+}
+
+.markdown h3 {
+ @apply text-2xl mt-8 mb-4 leading-snug;
+}
diff --git a/examples/cms-sitefinity/components/meta.tsx b/examples/cms-sitefinity/components/meta.tsx
new file mode 100644
index 0000000000000..24690de3d39da
--- /dev/null
+++ b/examples/cms-sitefinity/components/meta.tsx
@@ -0,0 +1,44 @@
+import Head from 'next/head'
+import { CMS_NAME, HOME_OG_IMAGE_URL } from '../lib/constants'
+
+const Meta = () => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
+
+export default Meta
diff --git a/examples/cms-sitefinity/components/more-stories.tsx b/examples/cms-sitefinity/components/more-stories.tsx
new file mode 100644
index 0000000000000..0bcb92808cf15
--- /dev/null
+++ b/examples/cms-sitefinity/components/more-stories.tsx
@@ -0,0 +1,31 @@
+import PostPreview from './post-preview'
+import type Post from '../interfaces/post'
+
+type Props = {
+ posts: Post[]
+}
+
+const MoreStories = ({ posts }: Props) => {
+ return (
+
+
+ More Stories
+
+
+ {posts.map((post) => (
+
+ ))}
+
+
+ )
+}
+
+export default MoreStories
diff --git a/examples/cms-sitefinity/components/post-body.tsx b/examples/cms-sitefinity/components/post-body.tsx
new file mode 100644
index 0000000000000..cfb1f70cede82
--- /dev/null
+++ b/examples/cms-sitefinity/components/post-body.tsx
@@ -0,0 +1,18 @@
+import markdownStyles from './markdown-styles.module.css'
+
+type Props = {
+ content: string
+}
+
+const PostBody = ({ content }: Props) => {
+ return (
+
+ )
+}
+
+export default PostBody
diff --git a/examples/cms-sitefinity/components/post-header.tsx b/examples/cms-sitefinity/components/post-header.tsx
new file mode 100644
index 0000000000000..a2316fb32492c
--- /dev/null
+++ b/examples/cms-sitefinity/components/post-header.tsx
@@ -0,0 +1,36 @@
+import Avatar from './avatar'
+import DateFormatter from './date-formatter'
+import CoverImage from './cover-image'
+import PostTitle from './post-title'
+import type Author from '../interfaces/author'
+
+type Props = {
+ title: string
+ coverImage: string
+ date: string
+ author: Author
+}
+
+const PostHeader = ({ title, coverImage, date, author }: Props) => {
+ return (
+ <>
+ {title}
+
+
+
+
+
+ >
+ )
+}
+
+export default PostHeader
diff --git a/examples/cms-sitefinity/components/post-preview.tsx b/examples/cms-sitefinity/components/post-preview.tsx
new file mode 100644
index 0000000000000..39fcd8ef6e834
--- /dev/null
+++ b/examples/cms-sitefinity/components/post-preview.tsx
@@ -0,0 +1,43 @@
+import Avatar from './avatar'
+import DateFormatter from './date-formatter'
+import CoverImage from './cover-image'
+import Link from 'next/link'
+import type Author from '../interfaces/author'
+
+type Props = {
+ title: string
+ coverImage: string
+ date: string
+ excerpt: string
+ author: Author
+ slug: string
+}
+
+const PostPreview = ({
+ title,
+ coverImage,
+ date,
+ excerpt,
+ author,
+ slug,
+}: Props) => {
+ return (
+
+
+
+
+
+
+
+
+
{excerpt}
+
+
+ )
+}
+
+export default PostPreview
diff --git a/examples/cms-sitefinity/components/post-title.tsx b/examples/cms-sitefinity/components/post-title.tsx
new file mode 100644
index 0000000000000..74dc0fdb10aa9
--- /dev/null
+++ b/examples/cms-sitefinity/components/post-title.tsx
@@ -0,0 +1,15 @@
+import { ReactNode } from 'react'
+
+type Props = {
+ children?: ReactNode
+}
+
+const PostTitle = ({ children }: Props) => {
+ return (
+
+ {children}
+
+ )
+}
+
+export default PostTitle
diff --git a/examples/cms-sitefinity/components/section-separator.tsx b/examples/cms-sitefinity/components/section-separator.tsx
new file mode 100644
index 0000000000000..5205e528e4554
--- /dev/null
+++ b/examples/cms-sitefinity/components/section-separator.tsx
@@ -0,0 +1,5 @@
+const SectionSeparator = () => {
+ return
+}
+
+export default SectionSeparator
diff --git a/examples/cms-sitefinity/interfaces/author.ts b/examples/cms-sitefinity/interfaces/author.ts
new file mode 100644
index 0000000000000..4d9892b341508
--- /dev/null
+++ b/examples/cms-sitefinity/interfaces/author.ts
@@ -0,0 +1,6 @@
+type Author = {
+ name: string
+ picture: string
+}
+
+export default Author
diff --git a/examples/cms-sitefinity/interfaces/post.ts b/examples/cms-sitefinity/interfaces/post.ts
new file mode 100644
index 0000000000000..179bf746fbc4d
--- /dev/null
+++ b/examples/cms-sitefinity/interfaces/post.ts
@@ -0,0 +1,16 @@
+import type Author from './author'
+
+type PostType = {
+ slug: string
+ title: string
+ date: string
+ coverImage: string
+ author: Author
+ excerpt: string
+ ogImage: {
+ url: string
+ }
+ content: string
+}
+
+export default PostType
diff --git a/examples/cms-sitefinity/lib/api.ts b/examples/cms-sitefinity/lib/api.ts
new file mode 100644
index 0000000000000..0dfab0b4cd19d
--- /dev/null
+++ b/examples/cms-sitefinity/lib/api.ts
@@ -0,0 +1,140 @@
+import PostType from '../interfaces/post'
+
+export async function executeGraphQLForBlogPosts(
+ query: string
+): Promise {
+ const graphQLEndpoint = `${process.env.SF_API_URL}graphql`
+ const response = await fetch(graphQLEndpoint, {
+ method: 'POST',
+ body: JSON.stringify({ query }),
+ headers: { 'Content-Type': 'application/json' },
+ }).then((x) => x.json())
+ return response['data']['posts']
+}
+
+export async function getAllPostSlugsFromCms(): Promise {
+ var query = `
+ query {
+ posts {
+ itemDefaultUrl
+ }
+ }
+ `
+
+ const blogPosts = await executeGraphQLForBlogPosts(query);
+ const slugs = blogPosts.map((x) => x.itemDefaultUrl);
+ return slugs;
+}
+
+function transformImageUrl(url: string) {
+ if (!url.startsWith('http')) {
+ url = process.env.SF_URL + url.substring(1)
+ }
+
+ return url
+}
+
+function mapCmsBlog(source: CmsPost): PostType {
+ return {
+ content: source.content,
+ excerpt: source.excerpt,
+ date: source.dateCreated,
+ slug: source.itemDefaultUrl,
+ title: source.title,
+ author: {
+ name: source.authorOfPost[0].title,
+ picture: transformImageUrl(source.authorOfPost[0].picture[0].url),
+ },
+ coverImage: transformImageUrl(source.coverImage[0].url),
+ ogImage: {
+ url: transformImageUrl(source.openGraphImage[0].url),
+ },
+ }
+}
+
+export async function getPostBySlugFromCms(slug: string): Promise {
+ const modifiedSlug = slug
+ var query = `
+ query {
+ posts(_filter: {itemDefaultUrl: {_eq: "${modifiedSlug}"}}) {
+ id
+ title
+ excerpt
+ content
+ dateCreated
+ itemDefaultUrl
+ openGraphImage {
+ url
+ }
+ coverImage {
+ url
+ }
+ authorOfPost {
+ title
+ picture {
+ url
+ }
+ }
+ }
+ }
+ `
+
+ const blogPosts = (await executeGraphQLForBlogPosts(query)).map((x) =>
+ mapCmsBlog(x)
+ )
+ if (blogPosts.length > 0) return blogPosts[0]
+
+ return null
+}
+
+export async function getAllPostsFromCms(): Promise {
+ var query = `
+ query {
+ posts {
+ id
+ title
+ excerpt
+ content
+ dateCreated
+ itemDefaultUrl
+ openGraphImage {
+ url
+ }
+ coverImage {
+ url
+ }
+ authorOfPost {
+ title
+ picture {
+ url
+ }
+ }
+ }
+ }
+ `
+
+ const blogPosts = (await executeGraphQLForBlogPosts(query)).map((x) =>
+ mapCmsBlog(x)
+ )
+ return blogPosts
+}
+
+interface CmsPost {
+ title: string
+ excerpt: string
+ dateCreated: string
+ content: string
+ itemDefaultUrl: string
+ openGraphImage: {
+ url: string
+ }
+ coverImage: {
+ url: string
+ }
+ authorOfPost: {
+ title: string
+ picture: {
+ url: string
+ }
+ }
+}
diff --git a/examples/cms-sitefinity/lib/constants.ts b/examples/cms-sitefinity/lib/constants.ts
new file mode 100644
index 0000000000000..2d9d9657fc32b
--- /dev/null
+++ b/examples/cms-sitefinity/lib/constants.ts
@@ -0,0 +1,4 @@
+export const EXAMPLE_PATH = 'blog-starter'
+export const CMS_NAME = 'Sitefinity'
+export const HOME_OG_IMAGE_URL =
+ 'https://og-image.vercel.app/Next.js%20Blog%20Starter%20Example.png?theme=light&md=1&fontSize=100px&images=https%3A%2F%2Fassets.vercel.com%2Fimage%2Fupload%2Ffront%2Fassets%2Fdesign%2Fnextjs-black-logo.svg'
diff --git a/examples/cms-sitefinity/package.json b/examples/cms-sitefinity/package.json
new file mode 100644
index 0000000000000..c207fa7af896c
--- /dev/null
+++ b/examples/cms-sitefinity/package.json
@@ -0,0 +1,24 @@
+{
+ "private": true,
+ "scripts": {
+ "dev": "next",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "classnames": "^2.3.1",
+ "date-fns": "^2.28.0",
+ "next": "latest",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/node": "^18.0.3",
+ "@types/react": "^18.0.15",
+ "@types/react-dom": "^18.0.6",
+ "autoprefixer": "^10.4.7",
+ "postcss": "^8.4.14",
+ "tailwindcss": "^3.1.4",
+ "typescript": "^4.7.4"
+ }
+}
diff --git a/examples/cms-sitefinity/pages/_app.tsx b/examples/cms-sitefinity/pages/_app.tsx
new file mode 100644
index 0000000000000..6ac887c043040
--- /dev/null
+++ b/examples/cms-sitefinity/pages/_app.tsx
@@ -0,0 +1,6 @@
+import { AppProps } from 'next/app'
+import '../styles/index.css'
+
+export default function MyApp({ Component, pageProps }: AppProps) {
+ return
+}
diff --git a/examples/cms-sitefinity/pages/index.tsx b/examples/cms-sitefinity/pages/index.tsx
new file mode 100644
index 0000000000000..69a46d445c3a6
--- /dev/null
+++ b/examples/cms-sitefinity/pages/index.tsx
@@ -0,0 +1,49 @@
+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 { getAllPostsFromCms, getAllPostSlugsFromCms } from '../lib/api'
+import Head from 'next/head'
+import { CMS_NAME } from '../lib/constants'
+import Post from '../interfaces/post'
+
+type Props = {
+ allPosts: Post[]
+}
+
+export default function Index({ allPosts }: Props) {
+ const heroPost = allPosts[0]
+ const morePosts = allPosts.slice(1)
+ return (
+ <>
+
+
+ Next.js Blog Example with {CMS_NAME}
+
+
+
+ {heroPost && (
+
+ )}
+ {morePosts.length > 0 && }
+
+
+ >
+ )
+}
+
+export const getStaticProps = async () => {
+ const allPosts = await getAllPostsFromCms()
+
+ return {
+ props: { allPosts },
+ }
+}
diff --git a/examples/cms-sitefinity/pages/posts/[...slug].tsx b/examples/cms-sitefinity/pages/posts/[...slug].tsx
new file mode 100644
index 0000000000000..941fda951775e
--- /dev/null
+++ b/examples/cms-sitefinity/pages/posts/[...slug].tsx
@@ -0,0 +1,85 @@
+import { useRouter } from 'next/router'
+import ErrorPage from 'next/error'
+import Container from '../../components/container'
+import PostBody from '../../components/post-body'
+import Header from '../../components/header'
+import PostHeader from '../../components/post-header'
+import Layout from '../../components/layout'
+import { getAllPostSlugsFromCms, getPostBySlugFromCms } from '../../lib/api'
+import PostTitle from '../../components/post-title'
+import Head from 'next/head'
+import { CMS_NAME } from '../../lib/constants'
+import type PostType from '../../interfaces/post'
+
+type Props = {
+ post: PostType
+ morePosts: PostType[]
+ preview?: boolean
+}
+
+export default function Post({ post, morePosts, preview }: Props) {
+ const router = useRouter()
+ if (!router.isFallback && !post?.slug) {
+ return
+ }
+ return (
+
+
+
+ {router.isFallback ? (
+ Loading…
+ ) : (
+ <>
+
+
+
+ {post.title} | Next.js Blog Example with {CMS_NAME}
+
+
+
+
+
+
+ >
+ )}
+
+
+ )
+}
+
+type Params = {
+ params: {
+ slug: string[]
+ }
+}
+
+export async function getStaticProps({ params }: Params) {
+ debugger
+ const post = await getPostBySlugFromCms('/' + params.slug.join('/'))
+
+ return {
+ props: {
+ post,
+ },
+ }
+}
+
+export async function getStaticPaths() {
+ const slugs = await getAllPostSlugsFromCms()
+
+ return {
+ paths: slugs.map((slug) => {
+ return {
+ params: {
+ slug: slug.split('/').splice(1),
+ },
+ }
+ }),
+ fallback: false,
+ }
+}
diff --git a/examples/cms-sitefinity/postcss.config.js b/examples/cms-sitefinity/postcss.config.js
new file mode 100644
index 0000000000000..3fa0a9514dc9d
--- /dev/null
+++ b/examples/cms-sitefinity/postcss.config.js
@@ -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: {},
+ },
+}
diff --git a/examples/cms-sitefinity/public/favicon/android-chrome-192x192.png b/examples/cms-sitefinity/public/favicon/android-chrome-192x192.png
new file mode 100644
index 0000000000000..2f07282a59cda
Binary files /dev/null and b/examples/cms-sitefinity/public/favicon/android-chrome-192x192.png differ
diff --git a/examples/cms-sitefinity/public/favicon/android-chrome-512x512.png b/examples/cms-sitefinity/public/favicon/android-chrome-512x512.png
new file mode 100644
index 0000000000000..dbb0faea84049
Binary files /dev/null and b/examples/cms-sitefinity/public/favicon/android-chrome-512x512.png differ
diff --git a/examples/cms-sitefinity/public/favicon/apple-touch-icon.png b/examples/cms-sitefinity/public/favicon/apple-touch-icon.png
new file mode 100644
index 0000000000000..8f4033b2a8b35
Binary files /dev/null and b/examples/cms-sitefinity/public/favicon/apple-touch-icon.png differ
diff --git a/examples/cms-sitefinity/public/favicon/browserconfig.xml b/examples/cms-sitefinity/public/favicon/browserconfig.xml
new file mode 100644
index 0000000000000..9824d87b11517
--- /dev/null
+++ b/examples/cms-sitefinity/public/favicon/browserconfig.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+ #000000
+
+
+
diff --git a/examples/cms-sitefinity/public/favicon/favicon-16x16.png b/examples/cms-sitefinity/public/favicon/favicon-16x16.png
new file mode 100644
index 0000000000000..29deaf6716e77
Binary files /dev/null and b/examples/cms-sitefinity/public/favicon/favicon-16x16.png differ
diff --git a/examples/cms-sitefinity/public/favicon/favicon-32x32.png b/examples/cms-sitefinity/public/favicon/favicon-32x32.png
new file mode 100644
index 0000000000000..e3b4277bf093d
Binary files /dev/null and b/examples/cms-sitefinity/public/favicon/favicon-32x32.png differ
diff --git a/examples/cms-sitefinity/public/favicon/favicon.ico b/examples/cms-sitefinity/public/favicon/favicon.ico
new file mode 100644
index 0000000000000..ea2f437d9db65
Binary files /dev/null and b/examples/cms-sitefinity/public/favicon/favicon.ico differ
diff --git a/examples/cms-sitefinity/public/favicon/mstile-150x150.png b/examples/cms-sitefinity/public/favicon/mstile-150x150.png
new file mode 100644
index 0000000000000..f2dfd904bf1be
Binary files /dev/null and b/examples/cms-sitefinity/public/favicon/mstile-150x150.png differ
diff --git a/examples/cms-sitefinity/public/favicon/safari-pinned-tab.svg b/examples/cms-sitefinity/public/favicon/safari-pinned-tab.svg
new file mode 100644
index 0000000000000..72ab6e050cb11
--- /dev/null
+++ b/examples/cms-sitefinity/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-sitefinity/public/favicon/site.webmanifest b/examples/cms-sitefinity/public/favicon/site.webmanifest
new file mode 100644
index 0000000000000..a672d9a233c59
--- /dev/null
+++ b/examples/cms-sitefinity/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-sitefinity/sitefinity/SitefinityExport.zip b/examples/cms-sitefinity/sitefinity/SitefinityExport.zip
new file mode 100644
index 0000000000000..5528fae93bc73
Binary files /dev/null and b/examples/cms-sitefinity/sitefinity/SitefinityExport.zip differ
diff --git a/examples/cms-sitefinity/styles/index.css b/examples/cms-sitefinity/styles/index.css
new file mode 100644
index 0000000000000..b5c61c956711f
--- /dev/null
+++ b/examples/cms-sitefinity/styles/index.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/examples/cms-sitefinity/tailwind.config.js b/examples/cms-sitefinity/tailwind.config.js
new file mode 100644
index 0000000000000..798640446b960
--- /dev/null
+++ b/examples/cms-sitefinity/tailwind.config.js
@@ -0,0 +1,34 @@
+module.exports = {
+ content: ['./components/**/*.tsx', './pages/**/*.tsx'],
+ 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: {
+ sm: '0 5px 10px rgba(0, 0, 0, 0.12)',
+ md: '0 8px 30px rgba(0, 0, 0, 0.12)',
+ },
+ },
+ },
+ plugins: [],
+}
diff --git a/examples/cms-sitefinity/tsconfig.json b/examples/cms-sitefinity/tsconfig.json
new file mode 100644
index 0000000000000..3479893cf98cf
--- /dev/null
+++ b/examples/cms-sitefinity/tsconfig.json
@@ -0,0 +1,20 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "module": "esnext",
+ "jsx": "preserve",
+ "strict": false,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "noEmit": true,
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "incremental": true
+ },
+ "exclude": ["node_modules"],
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
+}