Skip to content

Commit

Permalink
Merge branch 'canary' into shu/hw5l
Browse files Browse the repository at this point in the history
  • Loading branch information
kodiakhq[bot] committed Feb 27, 2023
2 parents 91dfdf7 + 69fe4ee commit 7451bcd
Show file tree
Hide file tree
Showing 62 changed files with 819 additions and 444 deletions.
52 changes: 52 additions & 0 deletions .github/workflows/test_examples.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# This file duplicates bunch of things from build_test_deploy

on:
workflow_dispatch:
inputs:
is_dispatched:
description: 'Leave this option enabled'
required: true
default: true
type: boolean
schedule:
- cron: '0 */4 * * *'

name: Test examples

env:
PNPM_VERSION: 7.24.3

jobs:
testExamples:
# Don't execute using cron on forks
if: (github.repository == 'vercel/next.js') || (inputs.is_dispatched == true)
name: Test Examples
runs-on: ubuntu-latest
timeout-minutes: 120
env:
NEXT_TELEMETRY_DISABLED: 1
strategy:
fail-fast: false
matrix:
node: [16, 18]
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 25
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off

- name: Setup node
uses: actions/setup-node@v3
with:
node-version: 16
check-latest: true

- run: npm i -g pnpm@${PNPM_VERSION}

- run: pnpm install
- run: pnpm build

- run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.28.1-focal /bin/bash -c "cd /work && curl -s https://install-node.vercel.app/v${{ matrix.node }} | FORCE=1 bash && node -v && npm i -g pnpm@${PNPM_VERSION} > /dev/null && NEXT_TEST_JOB=1 NEXT_TEST_MODE=start xvfb-run node run-tests.js --type examples >> /proc/1/fd/1"
name: Run test/examples
99 changes: 14 additions & 85 deletions examples/cms-sanity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,17 @@ You'll get:
# Configuration

- [Step 1. Set up the environment](#step-1-set-up-the-environment)
- [Step 2. Configure CORS for localhost](#step-2-configure-cors-for-localhost)
- [Step 3. Run Next.js locally in development mode](#step-3-run-nextjs-locally-in-development-mode)
- [Step 4. Populate content](#step-4-populate-content)
- [Step 5. Deploy to production & use Preview Mode from anywhere](#step-5-deploy-to-production--use-preview-mode-from-anywhere)
- [Step 2. Run Next.js locally in development mode](#step-3-run-nextjs-locally-in-development-mode)
- [Step 3. Populate content](#step-3-populate-content)
- [Step 4. Deploy to production & use Preview Mode from anywhere](#step-4-deploy-to-production--use-preview-mode-from-anywhere)
- [If you didn't Deploy with Vercel earlier do so now](#if-you-didnt-deploy-with-vercel-earlier-do-so-now)
- [Configure CORS for production](#configure-cors-for-production)
- [Add the preview secret environment variable](#add-the-preview-secret-environment-variable)
- [How to test locally that the secret is setup correctly](#how-to-test-locally-that-the-secret-is-setup-correctly)
- [How to start Preview Mode for Next.js in production from a local Studio](#how-to-start-preview-mode-for-nextjs-in-production-from-a-local-studio)
- [If you regret sending a preview link to someone](#if-you-regret-sending-a-preview-link-to-someone)
- [Step 6. Deploy your Studio and publish from anywhere](#step-6-deploy-your-studio-and-publish-from-anywhere)
- [Step 7. Setup Revalidation Webhook](#step-7-setup-revalidation-webhook)
- [Step 5. Deploy your Studio and publish from anywhere](#step-5-deploy-your-studio-and-publish-from-anywhere)
- [Step 6. Setup Revalidation Webhook](#step-6-setup-revalidation-webhook)
- [Testing the Webhook](#testing-the-webhook)
- [Next steps](#next-steps)

Expand All @@ -71,81 +70,7 @@ Download the environment variables needed to connect Next.js and Studio to your
npx vercel env pull
```

<details>
<summary>You can also set up manually</summary>

- [Bootstrap the example](#bootstrap-the-example)
- [Connect to a Sanity project](#connect-to-a-sanity-project)
- [Set up environment variables](#set-up-environment-variables)

If using the [integration] isn't an option. Or maybe you want to work locally first and deploy to Vercel later. Whatever the reason this guide shows you how to setup manually.

### Bootstrap the example

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):

```bash
npx create-next-app --example cms-sanity cms-sanity-app
```

```bash
yarn create next-app --example cms-sanity cms-sanity-app
```

```bash
pnpm create next-app --example cms-sanity cms-sanity-app
```

### Connect to a Sanity project

Run this to select from your existing Sanity projects, or create a new one:

```bash
(cd studio && npx @sanity/cli init)
```

The CLI will update [`sanity.json`] with the project ID and dataset name.

### 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 these variables in `.env.local`:

- `NEXT_PUBLIC_SANITY_PROJECT_ID` should be the `projectId` value from [`sanity.json`].
- `NEXT_PUBLIC_SANITY_DATASET` should be the `dataset` value from [`sanity.json`].
- `SANITY_API_READ_TOKEN` create an API token with `read-only` permissions:
- Run this to open your project settings or go to https://manage.sanity.io/ and open your project:
```bash
(cd studio && npx @sanity/cli manage)
```
- Go to **API** and the **Tokens** section at the bottom, launch its **Add API token** button.
- Name it `SANITY_API_READ_TOKEN`, set **Permissions** to `Viewer`.
- Hit **Save** and you can copy/paste the token.

Your `.env.local` file should look like this:

```bash
NEXT_PUBLIC_SANITY_PROJECT_ID=...
NEXT_PUBLIC_SANITY_DATASET=...
SANITY_API_READ_TOKEN=...
```

</details>

## Step 2. Configure CORS for localhost

Needed for live previewing unpublished/draft content.

```bash
npm --prefix studio run cors:add -- http://localhost:3000 --credentials
```

## Step 3. Run Next.js locally in development mode
## Step 2. Run Next.js locally in development mode

```bash
npm install && npm run dev
Expand All @@ -157,6 +82,8 @@ yarn install && 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).

Note: This also installs dependencies for Sanity Studio as a post-install step.

## Step 4. Populate content

In another terminal start up the studio:
Expand All @@ -167,6 +94,8 @@ npm run studio:dev

Your studio should be up and running on [http://localhost:3333](http://localhost:3333)!

### Create content

Create content in Sanity Studio and live preview it in Next.js, side-by-side, by opening these URLs:

- [`http://localhost:3333`](http://localhost:3333)
Expand Down Expand Up @@ -216,7 +145,7 @@ We're all set to do some content creation!

To exit Preview Mode, you can click on _"Click here to exit preview mode"_ at the top.

## Step 5. Deploy to production & use Preview Mode from anywhere
## Step 4. Deploy to production & use Preview Mode from anywhere

### If you didn't [Deploy with Vercel earlier](#step-1-set-up-the-environment) do so now

Expand Down Expand Up @@ -317,7 +246,7 @@ npx vercel env add SANITY_STUDIO_PREVIEW_SECRET
npx vercel --prod
```

## Step 6. Deploy your Studio and publish from anywhere
## Step 5. Deploy your Studio and publish from anywhere

Live previewing content is fun, but collaborating on content in real-time is next-level:

Expand All @@ -344,7 +273,7 @@ Success! Studio deployed to https://cms-sanity.sanity.studio/

This snippet is stripped from verbose information, you'll see a lot of extra stuff in your terminal.

## Step 7. Setup Revalidation Webhook
## Step 6. Setup Revalidation Webhook

Using GROQ Webhooks Next.js can rebuild pages that have changed content. It rebuilds so fast it can almost compete with Preview Mode.

Expand Down Expand Up @@ -373,7 +302,7 @@ npx vercel --prod
Wormhole into the [manager](https://manage.sanity.io/) by running:

```bash
(cd studio && npx @sanity/cli hook create)
(cd studio && npx sanity hook create)
```

- **Name** it "On-demand Revalidation".
Expand Down
1 change: 0 additions & 1 deletion examples/cms-sanity/components/cover-image.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export default function CoverImage({ title, slug, image: source, priority }) {
>
<Image
className="w-full h-auto"
layout="responsive"
width={2000}
height={1000}
alt={`Cover Image for ${title}`}
Expand Down
8 changes: 8 additions & 0 deletions examples/cms-sanity/components/landing-preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { usePreview } from '../lib/sanity'
import { indexQuery } from '../lib/queries'
import Landing from './landing'

export default function LandingPreview({ allPosts }) {
const previewAllPosts = usePreview(null, indexQuery)
return <Landing data={previewAllPosts ?? allPosts} preview />
}
34 changes: 34 additions & 0 deletions examples/cms-sanity/components/landing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Layout from './layout'
import Head from 'next/head'
import { CMS_NAME } from '../lib/constants'
import Container from './container'
import Intro from './intro'
import HeroPost from './hero-post'
import MoreStories from './more-stories'

export default function Landing({ allPosts, preview }) {
const [heroPost, ...morePosts] = allPosts || []
return (
<>
<Layout preview={preview}>
<Head>
<title>{`Next.js Blog Example with ${CMS_NAME}`}</title>
</Head>
<Container>
<Intro />
{heroPost && (
<HeroPost
title={heroPost.title}
coverImage={heroPost.coverImage}
date={heroPost.date}
author={heroPost.author}
slug={heroPost.slug}
excerpt={heroPost.excerpt}
/>
)}
{morePosts.length > 0 && <MoreStories posts={morePosts} />}
</Container>
</Layout>
</>
)
}
4 changes: 2 additions & 2 deletions examples/cms-sanity/components/more-stories.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import PostPreview from '../components/post-preview'
import PostPlug from './post-plug'

export default function MoreStories({ posts }) {
return (
Expand All @@ -8,7 +8,7 @@ export default function MoreStories({ posts }) {
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 md:gap-x-16 lg:gap-x-32 gap-y-20 md:gap-y-32 mb-32">
{posts.map((post) => (
<PostPreview
<PostPlug
key={post.slug}
title={post.title}
coverImage={post.coverImage}
Expand Down
31 changes: 31 additions & 0 deletions examples/cms-sanity/components/post-plug.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import Avatar from '../components/avatar'
import Date from '../components/date'
import CoverImage from './cover-image'
import Link from 'next/link'

export default function PostPlug({
title,
coverImage,
date,
excerpt,
author,
slug,
}) {
return (
<div>
<div className="mb-5">
<CoverImage slug={slug} title={title} image={coverImage} />
</div>
<h3 className="mb-3 text-3xl leading-snug">
<Link href={`/posts/${slug}`} className="hover:underline">
{title}
</Link>
</h3>
<div className="mb-4 text-lg">
<Date dateString={date} />
</div>
<p className="mb-4 text-lg leading-relaxed">{excerpt}</p>
{author && <Avatar name={author.name} picture={author.picture} />}
</div>
)
}
36 changes: 7 additions & 29 deletions examples/cms-sanity/components/post-preview.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,9 @@
import Avatar from '../components/avatar'
import Date from '../components/date'
import CoverImage from './cover-image'
import Link from 'next/link'
import { usePreview } from '../lib/sanity'
import { postQuery } from '../lib/queries'
import Post from './post'

export default function PostPreview({
title,
coverImage,
date,
excerpt,
author,
slug,
}) {
return (
<div>
<div className="mb-5">
<CoverImage slug={slug} title={title} image={coverImage} />
</div>
<h3 className="mb-3 text-3xl leading-snug">
<Link href={`/posts/${slug}`} className="hover:underline">
{title}
</Link>
</h3>
<div className="mb-4 text-lg">
<Date dateString={date} />
</div>
<p className="mb-4 text-lg leading-relaxed">{excerpt}</p>
{author && <Avatar name={author.name} picture={author.picture} />}
</div>
)
export default function PostPreview({ data }) {
const slug = data?.post?.slug
const previewData = usePreview(null, postQuery, { slug })
return <Post data={previewData ?? data} preview />
}

0 comments on commit 7451bcd

Please sign in to comment.