ant to pass to Jest
/** @type {import('jest').Config} */
const customJestConfig = {
  displayName: process.env.IS_WEBPACK_TEST ? 'webpack' : 'Turbopack',
  testMatch: ['**/*.test.js', '**/*.test.ts', '**/*.test.jsx', '**/*.test.tsx'],
  globalSetup: '<rootDir>/jest-global-setup.ts',
  setupFilesAfterEnv: ['<rootDir>/jest-setup-after-env.ts'],
  verbose: true,
  rootDir: 'test',
  roots: [
    '<rootDir>',
    '<rootDir>/../packages/next/src/',
    '<rootDir>/../packages/next-codemod/',
    '<rootDir>/../pac

ision: true,
  },
  modulePathIgnorePatterns: [
    '/\\.next/',
    // Prevents jest-haste-map warnings due to multiple versions of the same
    // package being vendored. Also means tests in `compiled` will be ignored.
    // Jest does not normalize/reso

kages/eslint-plugin-internal/',
    '<rootDir>/../packages/font/src/',
    '<rootDir>/../packages/next-routing/',
  ],
  haste: {
    // Throwing to avoid warnings creeping up over time polluting log output.
    throwOnModuleColl


*   pnpm eval <eval-name> --dry       preview without executing
 *   pnpm eval --all                   run every eval (slow — normally only CI does this)
 *   NEXT_SKIP_PACK=1 pnpm eval ...    reuse tarball from last run
 *
 * Mirrors run-tests.js: pack once, hand paths to child via env, forward args.
 *
 * We only pack `next`, not the whole workspace. The sandbox is remote Linux:
 *   - @next/swc: local darwin binary wouldn't run there; the sandbox downloads
 *     the right one at runtime (packages/next/s

ne place instead of
 * maintaining N committed experiment files that only differ by one line.
 */
const path = require('path')
const fs = require('fs')
const { execFileSync, spawnSync } = require('child_process')

const ROOT = __dirname

const EVALS_DIR =

rc/build/swc/index.ts).
 *   - @next/env etc: resolved from npm at the pinned canary version.
 *
 * The experiments/ dir is generated fresh on every run and gitignored. This
 * keeps the two variants (baseline vs. AGENTS.md) in o


ess.env.RSPACK_BINDING = require('node:path').dirname(
  require.resolve('@next/rspack-binding')
)

const binding = require('@next/rspack-binding')

// Register the plugins exported by `crates/binding/src/lib.rs`.
binding.registerNextExternalsPlugin()
binding.registerForceCompleteRuntimePlugin()

const core = require('@rspack/core')

const NextExternalsPlugin = core.experiments.createNativePlugin(
  'NextExternalsPlugin',
  function (options) {
    return options
  }
)

const ForceCompleteRuntimePlugin = co

untimePlugin',
  function () {
    return {}
  }
)

Object.defineProperty(core, 'NextExternalsPlugin', {
  value: NextExternalsPlugin,
})

Object.defineProperty(core, 'ForceCompleteRuntimePlugin', {
  value: ForceCompleteRuntimePlugin,
})

module.exports =

re.experiments.createNativePlugin(
  'ForceCompleteR


React from "react";
import { useForm, ValidationError } from "@formspree/react";
import formStyles from "../styles/form.module.css";

export default function ContactForm() {
  const [state, handleSubmit] = useForm(process.env.NEXT_PUBLIC_FORM);
  if (state.succeeded) {
    return
Thanks for your submission!
;
  }
  return (
    <form onSubmit={handleSubmit} className={formStyles.container}>

        Your email:

      <input

es.fieldErrors}
      />
      <label htmlFor="message" className={formStyles.labels}>
        Your message:
      </label>
      <textarea
        id="message"
        name="message"
        className={`${formStyles.inputs} ${formStyles.textarea}`}

    id="email"
        type="email"
        name="email"
        className={formStyles.inputs}
      />
      <ValidationError
        prefix="Email"
        field="email"
        errors={state.errors}
        className={formStyl


from "react-redux";
import Header from "../shared/components/header";
import { useRematchDispatch } from "../shared/utils";

const Home = () => {
  const counter = useSelector((state) => state.counter);
  const dispatch = useDispatch();
  const { increment } = useRematchDispatch((dispatch) => ({
    increment: dispatch.counter.increment,
  }));

  return (

 Counter

The count is {counter}

        <button onClick={dispatch.counter.increment}

ncrement(1)}>
          increment (using dispatch function)
        </button>
        <button onClick={() => increment(5)}>increment by 5</button>
        <button onClick={dispatch.counter.incrementAsync}>
          incrementAsync
        </button>
      <

>increment</button>
        <button onClick={() => i


StitchesLogo = () => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    width="35"
    height="35"
    viewBox="0 0 35 35"
    fill="none"
  >
    <circle
      cx="17.5"
      cy="17.5"
      r="14.5"
      stroke="currentColor"
      strokeWidth="2"
    />
    <path d="M12.8184 31.3218L31.8709 20.3218" stroke="currentColor" />
    <path d="M3.31836 14.8674L22.3709 3.86743" stroke="currentColor" />
    <path
      d="M8.65332 29.1077L25.9738 19.1077"
      stroke="currentColor"
      strokeLinecap="round"

lor"
      strokeLinecap="round"
      strokeLinejoin="round"
    />
    <path
      d="M16.6973 12.2302L25.9736 19.1078"
      stroke="currentColor"
      strokeLinecap="round"
      strokeLinejoin="round"
    />
    <path
      d="M9.21582 16.0815L19.045

      strokeLinejoin="round"
    />
    <path
      d="M9.21582 16.0815L26.5363 6.08154"
      stroke="currentColor"
      strokeLinecap="round"
    />
    <path
      d="M13.2334 14.2297L22.5099 21.1077"
      stroke="currentCo


WR from "swr";
import fetcher from "libs/fetcher";
import styles from "./Gallery.module.css";
import UImage from "components/UImage";

interface GalleryProps {
  id_collection?: number;
}

const Gallery = ({ id_collection }: GalleryProps) => {
  const { data, error } = useSWR(
    "/api/photo" + (id_collection ? `/${id_collection}` : ""),
    fetcher,
  );

  if (error) return
failed to load
;

  if (!data) return
loading...
;

  return (
    <section className={styles.gallery_container}

ription }) => (
        <UImage
          id={id}
          urls={urls}
          altDescription={alt_description ? alt_description : description}
          key={`${id}_uimage_component`}
        />
      ))}
    </section>
  );
};

export default Gallery;

>
      {data.map(({ id, urls, alt_description, desc


@type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
    "./slices/**/*.{js,ts,jsx,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: {


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"

n/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

   />
      <link rel="manifest" href="/favicon/site.webmanifest" />
      <link
        rel="mask-icon"
        href="/favicon/safari-pinned-tab.svg"
        color="#000000"
      />
      <link rel="shortcut icon" href="/favico


onst { promises: fs } = require("fs");
const path = require("path");
const RSS = require("rss");
const matter = require("gray-matter");

async function generate() {
  const feed = new RSS({
    title: "Your Name",
    site_url: "https://yoursite.com",
    feed_url: "https://yoursite.com/feed.xml",
  });

  const posts = await fs.readdir(path.join(__dirname, "..", "pages", "posts"));

  await Promise.all(
    posts.map(async (name) => {
      if (name.startsWith("index.")) return;

      const content = awai

?/, ""),
        date: frontmatter.data.date,
        description: frontmatter.data.description,
        categories: frontmatter.data.tag.split(", "),
        author: frontmatter.data.author,
      });
    }),
  );

  await fs.writeFile("./public/feed.xml"

t fs.readFile(
        path.join(__dirname, "..", "pages", "posts", name),
      );
      const frontmatter = matter(content);

      feed.item({
        title: frontmatter.data.title,
        url: "/posts/" + name.replace(/\.mdx


ort { CSSTransition } from "react-transition-group";
import { gsap } from "gsap";
import Home from "../components/Home";

export default function HomePage() {
  const onEnter = (node: any) => {
    gsap.from(
      [node.children[0].firstElementChild, node.children[0].lastElementChild],
      0.6,
      {
        y: 30,
        delay: 0.6,
        ease: "power3.InOut",
        opacity: 0,
        stagger: {
          amount: 0.6,
        },
      },
    );
  };
  const onExit = (node: any) => {
    gsap.to(

(
    <>

        <CSSTransition
          in={true}
          timeout={1200}
          classNames="page"
          onExit={onExit}
          onEntering={onEnter}
          unmountOnExit
        >
          <div className="

      [node.children[0].firstElementChild, node.children[0].lastElementChild],
      0.6,
      {
        y: -30,
        ease: "power3.InOut",
        stagger: {
          amount: 0.2,
        },
      },
    );
  };

  return


': 'documentation',
  'Example Changes': 'examples',
}

const fallbackSection = 'Misc Changes'

// --------------------------------------------------

const prNumberRegex = /\(#([-0-9]+)\)$/

const getCommitPullRequest = async (commit, github) => {
  const match = prNumberRegex.exec(commit.title)

  if (!match) {
    return null
  }

  const number = parseInt(match[1], 10)

  if (!number) {
    return null
  }

  const { data } = await github.connection.pullRequests.get({
    owner: github.repoDetails.user,

bel] of Object.entries(sectionLabelMap)) {
    if (labels.some((prLabel) => prLabel.name === label)) {
      return section
    }
  }

  return null
}

const groupByLabels = async (commits, github) => {
  // Initialize the sections object with empty arrays

    repo: github.repoDetails.repo,
    number,
  })

  return data
}

const getSectionForPullRequest = (pullRequest) => {
  const { labels } = pullRequest

  // sections defined first will take priority
  for (const [section, la


tProfile {
  // Env vars that always affect test behavior (non-NEXT prefixed).
  static EXTRA_ENV_VARS = [
    'IS_WEBPACK_TEST',
    'IS_TURBOPACK_TEST',
    'TURBOPACK_DEV',
    'TURBOPACK_BUILD',
    'BROWSER_NAME',
    'DEVICE_NAME',
  ]

  // NEXT_* / __NEXT* vars that are operational, not behavioral.
  static IGNORED_VARS = new Set([
    'NEXT_TELEMETRY_DISABLED',
    'NEXT_TEST_JOB',
    'NEXT_JUNIT_TEST_REPORT',
    'NEXT_TEST_PREFER_OFFLINE',
    'NEXT_CI_RUNNER',
    'NEXT_E2E_TEST_TIMEOUT',
    '

ted once at construction
  // from a snapshot of process.env. The actual cache key for the workflow
  // is `input_step_key` (see `.github/workflows/build_reusable.yml`).
  entries
  // NEXT_*/__NEXT* vars that matched the pattern but were ignored.
  ignor

NEXT_TURBOPACK_IO_CONCURRENCY',
    'NEXT_TEST_PASSED_FILE',
    'TURBO_TASKS_AVAILABLE_PARALLELISM',
  ])

  // All key=value pairs identifying this test profile, sorted by key.
  // Used for the diagnostic `log()` output. Compu


wPackageName) {
  console.error('Usage: node change-npm-name.js <new-package-name>')
  console.error('Example: node change-npm-name.js @next/rspack-core')
  process.exit(1)
}

const bindingPackageName = newPackageName.replace(/core/g, 'binding')

console.log(`Core package name: ${newPackageName}`)
console.log(`Binding package name: ${bindingPackageName}`)
console.log(`GitHub Repository: ${process.env.GITHUB_REPOSITORY || 'not set'}`)

function updatePackageJson(filePath, packageName) {
  try {
    if (!fs.e

ry URL to match current GitHub repo for provenance validation
    if (packageJson.repository && packageJson.repository.url) {
      const githubRepo = process.env.GITHUB_REPOSITORY
      if (githubRepo) {
        packageJson.repository.url = `git+https://g

xistsSync(filePath)) {
      console.warn(`Package.json not found: ${filePath}`)
      return
    }

    const packageJson = JSON.parse(fs.readFileSync(filePath, 'utf8'))
    packageJson.name = packageName

    // Update reposito


  musl = isMuslFromReport()
    }
    if (musl === null) {
      musl = isMuslFromChildProcess()
    }
  }
  return musl
}

const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-')

const isMuslFromFilesystem = () => {
  try {
    return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl')
  } catch {
    return null
  }
}

const isMuslFromReport = () => {
  let report = null
  if (typeof process.report?.getReport === 'function') {
    process.report.excludeNetwork = true
    report =

sFileMusl)) {
      return true
    }
  }
  return false
}

const isMuslFromChildProcess = () => {
  try {
    return require('child_process')
      .execSync('ldd --version', { encoding: 'utf8' })
      .includes('musl')
  } catch (e) {
    // If we reach

process.report.getReport()
  }
  if (!report) {
    return null
  }
  if (report.header && report.header.glibcVersionRuntime) {
    return false
  }
  if (Array.isArray(report.sharedObjects)) {
    if (report.sharedObjects.some(i


Title,
  CardBody,
} from "reactstrap";

export default function Home() {
  return (
    <Container className="md-container">

        <title>ReactJS with reactstrap</title>
        <link rel="icon" href="/favicon-32x32.png" />

      <Container>

          Welcome to Next.js!

          Get started by editing pages/index.js

        <Container>
          <Row>
            <Col sm="6">

PI.
                  </CardText>
                  <Button color="primary" href="https://nextjs.org/docs">
                    More →
                  </Button>
                </CardBody>
              </Card>
            </Col>
            <Col sm

           <Card className="my-3">
                <CardBody>
                  <CardTitle tag="h5">Documentation</CardTitle>
                  <CardText>
                    Find in-depth information about Next.js features and A


"react";
import ClientOnlyPortal from "./ClientOnlyPortal";

export default function Modal() {
  const [open, setOpen] = useState();

  return (
    <>
      <button type="button" onClick={() => setOpen(true)}>
        Open Modal
      </button>
      {open && (
        <ClientOnlyPortal selector="#modal">

                This modal is rendered using{" "}
                <a
                  href="https://react.dev/re

tton type="button" onClick={() => setOpen(false)}>
                Close Modal
              </button>
            </div>
            <style jsx>{`
              :global(body) {
                overflow: hidden;
              }

              .backdrop {

ference/react-dom/createPortal"
                  target="_blank"
                  rel="noopener noreferrer"
                >
                  portals
                </a>
                .
              </p>
              <bu


ort { useMemo } from "react";
import { init } from "@rematch/core";
import { counter, github } from "./models";

let store;

const exampleInitialState = {
  counter: 5,
};

export const initStore = (initialState = exampleInitialState) =>
  init({
    models: {
      counter,
      github,
    },
    redux: {
      initialState,
    },
  });

export const initializeStore = (preloadedState) => {
  let _store = store ?? initStore(preloadedState);

  // After navigating to a page with an initial Redux state, me

    store = undefined;
  }

  // For SSG and SSR always create a new store
  if (typeof window === "undefined") return _store;
  // Create the store once in the client
  if (!store) store = _store;

  return _store;
};

export function useStore(initialStat

rge that state
  // with the current state in the store, and create a new store
  if (preloadedState && store) {
    _store = initStore({
      ...store.getState(),
      ...preloadedState,
    });
    // Reset the current store


om "react-redux";
import { useRematchDispatch } from "../shared/utils";
import { initializeStore } from "../shared/store";
import CounterDisplay from "../shared/components/counter-display";
import Header from "../shared/components/header";

const Github = (props) => {
  const github = useSelector((state) => state.github);
  const { users, isLoading } = github;
  const { fetchUsers } = useRematchDispatch((dispatch) => ({
    fetchUsers: dispatch.github.fetchUsers,
  }));

  const { usersList } = props;
  ret

 Users passed as property from getStaticProps

      {usersList.map((user) => (

             Username - {user.

urn (

 Github users

        Server rendered github user list. You can also reload the users from the
        api by clicking the Get users button below.


nst github = {
  state: {
    users: [],
    isLoading: false,
  }, // initial state
  reducers: {
    requestUsers(state) {
      return {
        users: [],
        isLoading: true,
      };
    },
    receiveUsers(state, payload) {
      return {
        isLoading: false,
        users: payload,
      };
    },
  },
  effects: {
    // handle state changes with impure functions.
    // use async/await for async actions
    async fetchUsers() {
      try {
        this.requestUsers();
        const respon

ch("https://api.github.com/users");
        const users = await response.json();
        this.receiveUsers(users);
        return users;
      } catch (err) {
        console.log(err);
        this.receiveUsers([]);
      }
    },
  },
};

export default g


 from "@stitches/react";
import { createStitches } from "@stitches/react";

export const {
  config,
  createTheme,
  css,
  getCssText,
  globalCss,
  styled,
  theme,
} = createStitches({
  theme: {
    colors: {
      hiContrast: "hsl(206,10%,5%)",
      loContrast: "white",

      gray100: "hsl(206,22%,99%)",
      gray200: "hsl(206,12%,97%)",
      gray300: "hsl(206,11%,92%)",
      gray400: "hsl(206,10%,84%)",
      gray500: "hsl(206,10%,76%)",
      gray600: "hsl(206,10%,44%)",

      purple100: "hsl


 } from "../stitches.config";

const Box = styled("div", {});

const Text = styled("p", {
  fontFamily: "$system",
  color: "$hiContrast",
});

const Link = styled("a", {
  fontFamily: "$system",
  textDecoration: "none",
  color: "$purple600",
});

const Container = styled("div", {
  marginX: "auto",
  paddingX: "$3",

  variants: {
    size: {
      1: {
        maxWidth: "300px",
      },
      2: {
        maxWidth: "585px",
      },
      3: {
        maxWidth: "865px",
      },
    },
  },
});

export

{ paddingY: "$6" }}>
      <Container size={{ "@initial": "1", "@bp1": "2" }}>
        <StitchesLogo />
        <Text as="h1">Hello, from Stitches.</Text>
        <Text>
          For full documentation, visit{" "}
          <Link href="https://stitches.de

 default function Home() {
  return (
    <Box css={


Head from "next/head";
import styles from "../styles/Home.module.css";
import ContactForm from "../components/contact-form";

export default function Home() {
  return (

        <title>Create Next App</title>
        <link rel="icon" href="/favicon.ico" />

          Welcome to Next.js!

        <p className={styles.descr

h3>
            <ContactForm />
          </div>
        </div>
      </main>

      <footer className={styles.footer}>
        <a
          href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"

iption}>
          Get started by editing{" "}
          pages/index.js

Contact Us</


import { useRouter } from "next/router";
import Link from "next/link";
import { format } from "url";

let counter = 0;

export async function getServerSideProps() {
  counter++;
  return { props: { initialPropsCounter: counter } };
}

export default function Index({ initialPropsCounter }) {
  const router = useRouter();
  const { pathname, query } = router;
  const reload = () => {
    router.push(format({ pathname, query }));
  };
  const incrementCounter = () => {
    const currentCounter = query.counter

Link>
      <button onClick={reload}>Reload</button>
      <button onClick={incrementCounter}>Change State Counter</button>

"getServerSideProps" ran for "{initialPropsCounter}" times.

Counter: "{query.counter || 0}".

? parseInt(query.counter) : 0;
    const href = `/?counter=${currentCounter + 1}`;

    router.push(href, href, { shallow: true });
  };

  return (

This is the Home Page

      <Link href="/about">About</


 from "@apollo/server";
import { startServerAndCreateNextHandler } from "@as-integrations/next";
import { makeExecutableSchema } from "@graphql-tools/schema";
import { gql } from "graphql-tag";

const typeDefs = gql`
  type Query {
    users: [User!]!
    user(username: String): User
  }
  type User {
    name: String
    username: String
  }
`;

const users = [
  { name: "Leeroy Jenkins", username: "leeroy" },
  { name: "Foo Bar", username: "foobar" },
];

const resolvers = {
  Query: {
    users() {

 {
      return users.find((user) => user.username === username);
    },
  },
};

export const schema = makeExecutableSchema({ typeDefs, resolvers });

const server = new ApolloServer({
  schema,
});

export default startServerAndCreateNextHandler(server);

 return users;
    },
    user(parent, { username })


SWR from "swr";
import fetcher from "libs/fetcher";
import Link from "next/link";
import styles from "./User.module.css";
import Social from "components/Social";

const User = () => {
  const { data, error } = useSWR("/api/user", fetcher);

  if (error) return
failed to load
;

  return (

      <Link href="/">
        {data && (
          <img
            src={data.profile_image.large}
            className={`${styles.headerImage} ${styles.borderCircle}`}

data.name}
          />
        )}
      </Link>

        <Link href="/">{data ? data.name : ""}</Link>

      {data ? <Social user={data} /> : ""}

{data ? data.bio : ""}

  );
}


ql from "../shared/query-graphql";

export default function UserProfile({ user }) {
  if (!user) {
    return
User Not Found
;
  }
  return (

      {user.username} is {user.name}

  );
}

export async function getStaticProps(context) {
  const { params } = context;
  const { username } = params;
  const { user = null } = await queryGraphql(
    `
    query($username: String) {
      user(username: $username) {
        name
        username
      }
    }
  `,
    { username },
  );

on getStaticPaths() {
  const { users } = (await queryGraphql(`
    query {
      users {
        username
      }
    }
  `)) as { users: { username: string }[] };

  return {
    paths: users.map(({ username }) => ({
      params: { username },
    })),

  return { props: { user } };
}

export async functi


useSWR from "swr";
import fetcher from "libs/fetcher";
import Link from "next/link";
import styles from "./Collections.module.css";

interface CollectionProps {
  id_collection?: number;
}

const Collections = ({ id_collection }: CollectionProps) => {
  const { data, error } = useSWR(
    "/api/collection" + (id_collection ? `/${id_collection}` : ""),
    fetcher,
  );

  if (error) return
failed to load
;

  if (!data) return
loading...
;

  return (

{styles.chip_remove}
              aria-label="Return to home"
            />
          </Link>
        ) : (
          <Link
            href={{ pathname: "/collection/[slug]", query: { id: id } }}
            as={`/collection/${slug}?id=${id}`}

      {data.map(({ id, title, slug }) =>
        id_collection ? (
          <Link href="/" key={`collection_${slug}`} className={styles.chip}>
            {title}
            <Link
              href="/"
              className=


{
  GetStaticProps,
  GetStaticPaths,
  InferGetStaticPropsType,
} from "next";
import Link from "next/link";
import { useRouter } from "next/router";
import LocaleSwitcher from "../../components/locale-switcher";

type GspPageProps = InferGetStaticPropsType<typeof getStaticProps>;

export default function GspPage(props: GspPageProps) {
  const router = useRouter();
  const { defaultLocale, isFallback, query } = router;

  if (isFallback) {
    return "Loading...";
  }

  return (

getSta

itcher />

      <Link href="/gsp">To getStaticProps page</Link>

      <Link href="/gssp">To getServerSideProps page</Link>

      <Link href="/">To index page</Link>

  );
}

type Props = {
  locale?: stri

ticProps page

Current slug: {query.slug}

Current locale: {props.locale}

Default locale: {defaultLocale}

Configured locales: {JSON.stringify(props.locales)}

      <LocaleSw


ort type { GetServerSideProps, InferGetServerSidePropsType } from "next";

import Link from "next/link";
import { useRouter } from "next/router";
import LocaleSwitcher from "../components/locale-switcher";

type GsspPageProps = InferGetServerSidePropsType<typeof getServerSideProps>;

export default function GsspPage(props: GsspPageProps) {
  const router = useRouter();
  const { defaultLocale } = router;

  return (

getServerSideProps page

Current locale: {props.locale}

first">To dynamic getStaticProps page</Link>

      <Link href="/">To index page</Link>

  );
}

type Props = {
  locale?: string;
  locales?: string[];
};

export const getServerSideProps: GetServerSideProps<Props> = as

Default locale: {defaultLocale}

Configured locales: {JSON.stringify(props.locales)}

      <LocaleSwitcher />

      <Link href="/gsp">To getStaticProps page</Link>

      <Link href="/gsp/


react";
import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client";
import { SchemaLink } from "@apollo/client/link/schema";
import { schema } from "../apollo/schema";
import merge from "deepmerge";

let apolloClient;

function createIsomorphLink() {
  if (typeof window === "undefined") {
    return new SchemaLink({ schema });
  } else {
    return new HttpLink({
      uri: "/api/graphql",
      credentials: "same-origin",
    });
  }
}

function createApolloClient() {
  return new ApolloClient(

ient();

  // If your page has Next.js data fetching methods that use Apollo Client, the initial state
  // gets hydrated here
  if (initialState) {
    // Get existing cache, loaded during client side data fetching
    const existingCache = _apolloClient.

{
    ssrMode: typeof window === "undefined",
    link: createIsomorphLink(),
    cache: new InMemoryCache(),
  });
}

export function initializeApollo(initialState = null) {
  const _apolloClient = apolloClient ?? createApolloCl


ort type { GetStaticProps, InferGetStaticPropsType } from "next";

import Link from "next/link";
import { useRouter } from "next/router";
import LocaleSwitcher from "../../components/locale-switcher";

type GspPageProps = InferGetStaticPropsType<typeof getStaticProps>;

export default function GspPage(props: GspPageProps) {
  const router = useRouter();
  const { defaultLocale } = router;

  return (

getStaticProps page

Current locale: {props.locale}

Default lo

etServerSideProps page</Link>

      <Link href="/">To index page</Link>

  );
}

type Props = {
  locale?: string;
  locales?: string[];
};

export const getStaticProps: GetStaticProps<Props> = async ({
  locale,
  loca

cale: {defaultLocale}

Configured locales: {JSON.stringify(props.locales)}

      <LocaleSwitcher />

      <Link href="/gsp/first">To dynamic getStaticProps page</Link>

      <Link href="/gssp">To g


 { NextApiRequest, NextApiResponse } from "next";
import Unsplash, { toJson } from "unsplash-js";
import fetch from "node-fetch";
global.fetch = fetch;

export default function download(req: NextApiRequest, res: NextApiResponse) {
  const {
    query: { id },
  } = req;

  const u = new Unsplash({ accessKey: process.env.UNSPLASH_ACCESS_KEY });

  return new Promise((resolve) => {
    u.photos
      .getPhoto(id.toString())
      .then(toJson)
      .then((json) => {
        u.photos.downloadPhoto(json);

  .then((r) => r.buffer())
          .then((buff) => {
            res.end(buff);
            resolve();
          })
          .catch((error) => {
            res.json(error);
            res.status(405).end();
            resolve();
          });
      }

      const filePath = json.links.download;
        const fileName = id + ".jpg";

        res.setHeader(
          "content-disposition",
          "attachment; filename=" + fileName,
        );

        fetch(filePath)


[KeyType];
};
/** Content for Author documents */
interface AuthorDocumentData {
  /**
   * Name field in *Author*
   *
   * - **Field Type**: Title
   * - **Placeholder**: Name of the author
   * - **API ID Path**: author.name
   * - **Tab**: Main
   * - **Documentation**: https://prismic.io/docs/core-concepts/rich-text-title
   *
   */
  name: prismicT.TitleField;
  /**
   * Picture field in *Author*
   *
   * - **Field Type**: Image
   * - **Placeholder**: *None*
   * - **API ID Path**: author.picture

rue`
 * - **Documentation**: https://prismic.io/docs/core-concepts/custom-types
 *
 * @typeParam Lang - Language API ID of the document.
 */
export type AuthorDocument<Lang extends string = string> =
  prismicT.PrismicDocumentWithoutUID<
    Simplify<Autho

 * - **Tab**: Main
   * - **Documentation**: https://prismic.io/docs/core-concepts/image
   *
   */
  picture: prismicT.ImageField<never>;
}
/**
 * Author document from Prismic
 *
 * - **API ID**: `author`
 * - **Repeatable**: `t


ponent from "../../../../slices/Text";

export default {
  title: "slices/Text",
};

export const _Default = () => (
  <MyComponent
    slice={{
      variation: "default",
      version: "sktwi1xtmkfgx8626",
      items: [{}],
      primary: {
        text: [
          {
            type: "paragraph",
            text: "Pariatur consequat eu eiusmod cillum velit excepteur ex sit sit dolore dolor labore ullamco.",
            spans: [],
          },
          {
            type: "paragraph",
            tex

,
          },
          {
            type: "paragraph",
            text: "Est consequat enim id quis consectetur exercitation reprehenderit. Nulla ut ut consequat ipsum nulla duis consequat nostrud eiusmod eiusmod ex incididunt consequat consequat minim

t: "Et nisi elit dolor pariatur pariatur nisi non est cillum aute.",
            spans: [],
          },
          {
            type: "paragraph",
            text: "Officia deserunt sunt ad ut anim quis.",
            spans: []


ink";
import { PrismicNextImage } from "@prismicio/next";
import { ImageField } from "@prismicio/types";
import cn from "classnames";

type CoverImageProps = {
  title: string;
  image: ImageField;
  href?: string;
};

export default function CoverImage({
  title,
  image: imageField,
  href,
}: CoverImageProps) {
  const image = (
    <PrismicNextImage
      field={imageField}
      width={2000}
      height={1000}
      imgixParams={{ fit: "crop", ar: "2:1" }}
      className={cn("shadow-small", {

-medium transition-shadow duration-200": href,
      })}
    />
  );

  return (
    <div className="sm:mx-0">
      {href ? (
        <Link href={href} aria-label={title}>
          {image}
        </Link>
      ) : (
        image
      )}
    </div>
  )


nk";
import { DateField, ImageField, TitleField } from "@prismicio/types";
import { PrismicText } from "@prismicio/react";
import { asText, isFilled } from "@prismicio/helpers";

import { AuthorContentRelationshipField } from "../lib/types";

import Avatar from "../components/avatar";
import CoverImage from "../components/cover-image";
import Date from "../components/date";

type HeroPostProps = {
  title: TitleField;
  coverImage: ImageField;
  date: DateField;
  excerpt: string;
  author: AuthorContentRel

mage title={asText(title)} href={href} image={coverImage} />

            <Lin

ationshipField;
  href: string;
};

export default function HeroPost({
  title,
  coverImage,
  date,
  excerpt,
  author,
  href,
}: HeroPostProps) {
  return (

        <CoverI


ic from "@prismicio/client";
import * as prismicNext from "@prismicio/next";

import sm from "../sm.json";

/**
 * The project's Prismic repository name.
 */
export const repositoryName = prismic.getRepositoryName(sm.apiEndpoint);

/**
 * Route definitions for Prismic documents.
 */
const routes: prismic.Route[] = [
  {
    type: "post",
    path: "/posts/:uid",
  },
];

/**
 * Creates a Prismic client for the project's repository. The client is used to
 * query content from the Prismic API.
 *
 * @param co

ort const createClient = ({
  previewData,
  req,
  ...config
}: prismicNext.CreateClientConfig = {}) => {
  const client = prismic.createClient(sm.apiEndpoint, {
    routes,
    ...config,
  });

  prismicNext.enableAutoPreviews({ client, previewData, req

nfig - Configuration for the Prismic client.
 */
exp


om "classnames";

import { EXAMPLE_PATH } from "../lib/constants";

import Container from "./container";

type AlertProps = {
  preview: boolean;
};

export default function Alert({ preview }: AlertProps) {
  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 i

>{" "}
              to exit preview mode.
            </>
          ) : (
            <>
              The source code for this blog is{" "}
              <a
                href={`https://github.com/vercel/next.js/tree/canary/examples/${EXAMPLE_PATH}`}

s page is a preview.{" "}
              <a
                href="/api/exit-preview"
                className="underline hover:text-cyan duration-200 transition-colors"
              >
                Click here
              </a


{ EXAMPLE_PATH } from "../lib/constants";

import Container from "./container";

export default function Footer() {
  return (

      <Container>

            Statically Generated with Next.js.

          <div className=

der 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

"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 bor


"@prismicio/client";

import PostPreview from "../components/post-preview";

type MoreStoriesProps = {
  posts: Content.PostDocument[];
};

export default function MoreStories({ posts }: MoreStoriesProps) {
  return (

        More Stories

        {posts.map((post) => (
          <PostPre

st.url}
            title={post.data.title}
            coverImage={post.data.cover_image}
            date={post.data.date}
            author={post.data.author}
            excerpt={post.data.excerpt}
          />
        ))}
      </div>
    </section>

view
            key={post.uid}
            href={po


from "next/link";
import { DateField, ImageField, TitleField } from "@prismicio/types";
import { PrismicText } from "@prismicio/react";
import { asText, isFilled } from "@prismicio/helpers";

import { AuthorContentRelationshipField } from "../lib/types";

import Avatar from "../components/avatar";
import Date from "../components/date";

import CoverImage from "./cover-image";

type PostPreviewProps = {
  title: TitleField;
  coverImage: ImageField;
  date: DateField;
  excerpt: string;
  author: AuthorConte

ge title={asText(title)} href={href} image={coverImage} />
      </div>
      <h3 className="text-3xl mb-3 leading-snug">
        <Link href={href} className="hover:underline">
          <PrismicText field={title} />
        </Link>
      </h3>
      <div

ntRelationshipField;
  href: string;
};

export default function PostPreview({
  title,
  coverImage,
  date,
  excerpt,
  author,
  href,
}: PostPreviewProps) {
  return (

        <CoverIma


rt { useRouter } from "next/router";
import { predicate } from "@prismicio/client";
import { asImageSrc, asText } from "@prismicio/helpers";

import { CMS_NAME } from "../../lib/constants";
import { PostDocumentWithAuthor } from "../../lib/types";
import { createClient } from "../../lib/prismic";

import Container from "../../components/container";
import Header from "../../components/header";
import Layout from "../../components/layout";
import MoreStories from "../../components/more-stories";
import PostB

 = {
  preview: boolean;
  post: PostDocumentWithAuthor;
  morePosts: PostDocumentWithAuthor[];
};

export default function Post({ post, morePosts, preview }: PostProps) {
  const router = useRouter();

  return (
    <Layout preview={preview}>
      <Cont

ody from "../../components/post-body";
import PostHeader from "../../components/post-header";
import PostTitle from "../../components/post-title";
import SectionSeparator from "../../components/section-separator";

type PostProps


URL } from "../lib/constants";

export default function Intro() {
  return (

        Blog.

        A statically generated blog example using{" "}
        <a
          href="https://nextjs.org/"
          className="underline hover:te

          Next.js
        </a>{" "}
        and{" "}
        <a
          href={CMS_URL}
          className="underline hover:text-success duration-200 transition-colors"
        >
          {CMS_NAME}
        </a>
        .
      </h4>
    </section>
  )


ad";
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 { createClient } from "../lib/prismic";
import { PostDocumentWithAuthor } from "../lib/types";
import { GetStaticPropsContext, GetStaticPropsResult } from "next";

type IndexProps = {
  preview: boolean;
  allPosts: Post

js Blog Example with ${CMS_NAME}`}</title>
        </Head>
        <Container>
          <Intro />
          {heroPost && (
            <HeroPost
              title={heroPost.data.title}
              href={heroPost.url}
              coverImage={heroPost

DocumentWithAuthor[];
};

export default function Index({ preview, allPosts }: IndexProps) {
  const [heroPost, ...morePosts] = allPosts;

  return (
    <>
      <Layout preview={preview}>
        <Head>
          <title>{`Next.


onentProps } from "@prismicio/react";
import { Content } from "@prismicio/client";

type TextProps = SliceComponentProps<Content.TextSlice>;

const Text = ({ slice }: TextProps) => {
  return (

      <PrismicRichText
        field={slice.primary.text}
        components={{
          heading2: ({ children }) => (

{children}

          ),
          heading3: ({ children }) => (
            <h2 cl

          ),
          paragraph: ({ children }) =>
{children}
,
          list: ({ children }) =>
{children}
,
          oList: ({ children }) =>
{children}
,
        }}

assName="text-2xl mt-8 mb-4 leading-snug">{children}


 { Html, Head, Main, NextScript } from "next/document";

export default function Document() {
  const meta = {
    title: "Next.js Blog Starter Kit",
    description: "Clone and deploy your own Next.js portfolio in minutes.",
    image: "https://assets.vercel.com/image/upload/q_auto/front/vercel/dps.png",
  };

  return (
    <Html lang="en">
      <Head>
        <meta name="robots" content="follow, index" />
        <meta name="description" content={meta.description} />
        <meta property="og:site_name

e="twitter:card" content="summary_large_image" />
        <meta name="twitter:site" content="@yourname" />
        <meta name="twitter:title" content={meta.title} />
        <meta name="twitter:description" content={meta.description} />
        <meta name=

" content={meta.title} />
        <meta property="og:description" content={meta.description} />
        <meta property="og:title" content={meta.title} />
        <meta property="og:image" content={meta.image} />
        <meta nam


 Post } from "@/interfaces/post";
import fs from "fs";
import matter from "gray-matter";
import { join } from "path";

const postsDirectory = join(process.cwd(), "_posts");

export function getPostSlugs() {
  return fs.readdirSync(postsDirectory);
}

export function getPostBySlug(slug: string) {
  const realSlug = slug.replace(/\.md$/, "");
  const fullPath = join(postsDirectory, `${realSlug}.md`);
  const fileContents = fs.readFileSync(fullPath, "utf8");
  const { data, content } = matter(fileContents);

;
}

export function getAllPosts(): Post[] {
  const slugs = getPostSlugs();
  const posts = slugs
    .map((slug) => getPostBySlug(slug))
    // sort posts by date in descending order
    .sort((post1, post2) => (post1.date > post2.date ? -1 : 1));
  retu

return { ...data, slug: realSlug, content } as Post


/_components/footer";
import { CMS_NAME, HOME_OG_IMAGE_URL } from "@/lib/constants";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import cn from "classnames";
import { ThemeSwitcher } from "./_components/theme-switcher";

import "./globals.css";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: `Next.js Blog Example with ${CMS_NAME}`,
  description: `A statically generated blog example using Next.js and ${CMS_NAME}.`,
  openGraph:

       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"
        />

{
    images: [HOME_OG_IMAGE_URL],
  },
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en" suppressHydrationWarning>
      <head>
        <link


iner from "@/app/_components/container";
import { EXAMPLE_PATH } from "@/lib/constants";

export function Footer() {
  return (

      <Container>

            Statically Generated with Next.js.
          </h

       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

3>
          <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/app/building-your-application/routing/layouts-and-templates"


Avatar from "@/app/_components/avatar";
import CoverImage from "@/app/_components/cover-image";
import { type Author } from "@/interfaces/author";
import Link from "next/link";
import DateFormatter from "./date-formatter";

type Props = {
  title: string;
  coverImage: string;
  date: string;
  excerpt: string;
  author: Author;
  slug: string;
};

export function HeroPost({
  title,
  coverImage,
  date,
  excerpt,
  author,
  slug,
}: Props) {
  return (

      <div className="mb-8 md:mb-16"

l leading-tight">
            <Link href={`/posts/${slug}`} className="hover:underline">
              {title}
            </Link>
          </h3>
          <div className="mb-4 md:mb-0 text-lg">
            <DateFormatter dateString={date} />
          </

>
        <CoverImage title={title} src={coverImage} slug={slug} />

          <h3 className="mb-4 text-4xl lg:text-5x


mport type { Config } from "tailwindcss";

const config: Config = {
  darkMode: "class",
  content: [
    "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
    "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
  ],
  theme: {
    extend: {
      backgroundImage: {
        "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
        "gradient-conic":
          "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
      },
      colors: {
        "accent-1":

 "#FAFAFA",
        "accent-2": "#EAEAEA",
        "accent-7": "#333",
        success: "#0070f3",
        cyan: "#79FFE1",
      },
      spacing: {
        28: "7rem",
      },
      letterSpacing: {
        tighter: "-.04em",


iner from "@/app/_components/container";
import { EXAMPLE_PATH } from "@/lib/constants";
import cn from "classnames";

type Props = {
  preview?: boolean;
};

const Alert = ({ preview }: Props) => {
  return (
    <div
      className={cn("border-b dark:bg-slate-800", {
        "bg-neutral-800 border-neutral-800 text-white": preview,
        "bg-neutral-50 border-neutral-200": !preview,
      })}
    >
      <Container>
        <div className="py-2 text-center text-sm">
          {preview ? (
            <>

here
              </a>{" "}
              to exit preview mode.
            </>
          ) : (
            <>
              The source code for this blog is{" "}
              <a
                href={`https://github.com/vercel/next.js/tree/canary/exampl

              This page is a preview.{" "}
              <a
                href="/api/exit-preview"
                className="underline hover:text-teal-300 duration-200 transition-colors"
              >
                Click


om "@prismicio/react";
import { asText, isFilled } from "@prismicio/helpers";
import { DateField, ImageField, TitleField } from "@prismicio/types";

import { AuthorContentRelationshipField } from "../lib/types";

import Avatar from "../components/avatar";
import Date from "../components/date";
import CoverImage from "../components/cover-image";
import PostTitle from "../components/post-title";

type PostHeaderProps = {
  title: TitleField;
  coverImage: ImageField;
  date: DateField;
  author: AuthorContent

assName="hidden md:block md:mb-12">
        {isFilled.contentRelationship(author) && (
          <Avatar
            name={asText(author.data.name)}
            picture={author.data.picture}
          />
        )}
      </div>
      <div className="mb-8 m

RelationshipField;
};

export default function PostHeader({
  title,
  coverImage,
  date,
  author,
}: PostHeaderProps) {
  return (
    <>
      <PostTitle>
        <PrismicText field={title} />
      </PostTitle>
      <div cl


/app/_components/container";
import { HeroPost } from "@/app/_components/hero-post";
import { Intro } from "@/app/_components/intro";
import { MoreStories } from "@/app/_components/more-stories";
import { getAllPosts } from "@/lib/api";

export default function Index() {
  const allPosts = getAllPosts();

  const heroPost = allPosts[0];

  const morePosts = allPosts.slice(1);

  return (
    <main>
      <Container>
        <Intro />
        <HeroPost
          title={heroPost.title}
          coverImage={h

mage}
          date={heroPost.date}
          author={heroPost.author}
          slug={heroPost.slug}
          excerpt={heroPost.excerpt}
        />
        {morePosts.length > 0 && <MoreStories posts={morePosts} />}
      </Container>
    </main>
  );
}


import DateFormatter from "./date-formatter";
import { PostTitle } from "@/app/_components/post-title";
import { type Author } from "@/interfaces/author";

type Props = {
  title: string;
  coverImage: string;
  date: string;
  author: Author;
};

export function PostHeader({ title, coverImage, date, author }: Props) {
  return (
    <>
      <PostTitle>{title}</PostTitle>
      <div className="hidden md:block md:mb-12">
        <Avatar name={author.name} picture={author.picture} />
      </div>
      <div

age title={title} src={coverImage} />

          <Avatar name={author.name} picture={author.picture} />

        <div className="mb-6 text-lg

 className="mb-8 md:mb-16 sm:mx-0">
        <CoverIm


ext/link";
import Avatar from "./avatar";
import CoverImage from "./cover-image";
import DateFormatter from "./date-formatter";

type Props = {
  title: string;
  coverImage: string;
  date: string;
  excerpt: string;
  author: Author;
  slug: string;
};

export function PostPreview({
  title,
  coverImage,
  date,
  excerpt,
  author,
  slug,
}: Props) {
  return (

        <CoverImage slug={slug} title={title} src={coverImage} />

      <h3 className="text

/${slug}`} className="hover:underline">
          {title}
        </Link>

        <DateFormatter dateString={date} />

{excerpt}

      <Avata

-3xl mb-3 leading-snug">
        <Link href={`/posts


"next";
import { notFound } from "next/navigation";
import { getAllPosts, getPostBySlug } from "@/lib/api";
import { CMS_NAME } from "@/lib/constants";
import markdownToHtml from "@/lib/markdownToHtml";
import Alert from "@/app/_components/alert";
import Container from "@/app/_components/container";
import Header from "@/app/_components/header";
import { PostBody } from "@/app/_components/post-body";
import { PostHeader } from "@/app/_components/post-header";

export default async function Post(props: Param

iew={post.preview} />
      <Container>
        <Header />
        <article className="mb-32">
          <PostHeader
            title={post.title}
            coverImage={post.coverImage}
            date={post.date}
            author={post.author}

s) {
  const params = await props.params;
  const post = getPostBySlug(params.slug);

  if (!post) {
    return notFound();
  }

  const content = await markdownToHtml(post.content || "");

  return (
    <main>
      <Alert prev


nction Home() {
  return (

        <title>Next.js & HLS.js</title>
        <link rel="icon" href="/favicon.ico" />

          Welcome to Next.js!

This is an example with HLS.js

          <VideoPlayer src="https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8" />

by{" "}

.

        <a
          href="https://mux.com?utm_source=create-next-app&utm_medium=with-hls-js&utm_campaign=create-next-ap

     <footer>
        <a
          href="https://vercel.com?utm_source=create-next-app&utm_medium=with-hls-js&utm_campaign=create-next-app"
          target="_blank"
          rel="noopener noreferrer"
        >
          Powered


 isFirst,
  isLast,
  isReleased,
  hasVoted,
  feature,
  pending,
  mutate,
}: {
  isFirst: boolean;
  isLast: boolean;
  isReleased: boolean;
  hasVoted: boolean;
  feature: Feature;
  pending: boolean;
  mutate: any;
}) {
  let upvoteWithId = upvote.bind(null, feature);
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  let [isPending, startTransition] = useTransition();

  return (
    <form
      action={upvoteWithId}
      onSubmit={(event) => {
        event.preventDefault();

ote(feature);
        });
      }}
      className={clsx(
        "p-6 mx-8 flex items-center border-t border-l border-r",
        isFirst && "rounded-t-md",
        isLast && "border-b rounded-b-md",
      )}
    >
      <button
        className={clsx(

 startTransition(async () => {
          mutate({
            updatedFeature: {
              ...feature,
              score: Number(feature.score) + 1,
            },
            pending: true,
          });
          await upv


act";

declare global {
  var updateDOM: () => void;
}

type ColorSchemePreference = "system" | "dark" | "light";

const STORAGE_KEY = "nextjs-blog-starter-theme";
const modes: ColorSchemePreference[] = ["system", "dark", "light"];

/** to reuse updateDOM function defined inside injected script */

/** function to be injected in script tag for avoiding FOUC (Flash of Unstyled Content) */
export const NoFOUCScript = (storageKey: string) => {
  /* can not use outside constants or function as this script will

teElement("style");
    css.textContent = "*,*:after,*:before{transition:none !important;}";
    document.head.appendChild(css);

    return () => {
      /* Force restyle */
      getComputedStyle(document.body);
      /* Wait for next tick before removin

be injected in a different context */
  const [SYSTEM, DARK, LIGHT] = ["system", "dark", "light"];

  /** Modify transition globally to avoid patched transitions */
  const modifyTransition = () => {
    const css = document.crea


erver";

import { kv } from "@vercel/kv";
import { revalidatePath } from "next/cache";
import { Feature } from "./types";

export async function saveFeature(feature: Feature, formData: FormData) {
  let newFeature = {
    ...feature,
    title: formData.get("feature") as string,
  };
  await kv.hset(`item:${newFeature.id}`, newFeature);
  await kv.zadd("items_by_score", {
    score: Number(newFeature.score),
    member: newFeature.id,
  });

  revalidatePath("/");
}

export async function saveEmail(formData

.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    return re.test(String(email).toLowerCase());
  }

  if (email && validateEmail(email)) {
    await kv.sadd("emails", email);
    revalidatePath("/");
  }
}

export async function upvote(feature: Feat


t { useEffect, useRef } from "react";
import { gsap } from "gsap";

type TitleProps = {
  lineContent: string;
  lineContent2: string;
};

export default function Title({ lineContent, lineContent2 }: TitleProps) {
  let line1 = useRef(null);
  let line2 = useRef(null);

  useEffect(() => {
    gsap.from([line1.current, line2.current], 0.8, {
      delay: 0.8,
      ease: "power3.out",
      y: 64,
      stagger: {
        amount: 0.15,
      },
    });
  }, [line1, line2]);

  return (
    <h1 className="pa

          {lineContent}

          {lineContent2}


VideoPlayer({ src }) {
  const videoRef = useRef(null);

  useEffect(() => {
    const video = videoRef.current;
    if (!video) return;

    video.controls = true;
    if (video.canPlayType("application/vnd.apple.mpegurl")) {
      // This will run in safari, where HLS is supported natively
      video.src = src;
    } else if (Hls.isSupported()) {
      // This will run in all other modern browsers
      const hls = new Hls();
      hls.loadSource(src);
      hls.attachMedia(video);
    } else {
      con

s not support MSE https://developer.mozilla.org/docs/Web/API/Media_Source_Extensions_API",
      );
    }
  }, [src, videoRef]);

  return (
    <>
      <video ref={videoRef} />
      <style jsx>{`
        video {
          max-width: 100%;
        }

sole.error(
        "This is an old browser that doe


m "./dotcms-image";
import Link from "next/link";

export const Bold = ({ children }) => {children};
export const Italic = ({ children }) => {children};
export const Strike = ({ children }) => <s>{children}</s>;
export const Underline = ({ children }) => {children};
export const DotLink = ({ attrs: { href, target }, children }) => {
  const regEx = /https?:\/\//;

  return regEx.test(href) ? (

      {children}

 TextNode = (props) => {
  const { marks = [], text } = props;
  const mark = marks[0] || { type: "", attrs: {} };
  const newProps = { ...props, marks: marks.slice(1) };
  const Component = nodeMarks[mark?.type];

  if (!Component) {
    return text;
  }

 </a>
  ) : (
    <Link href={href} target={target || "_self"}>
      {children}
    </Link>
  );
};

const nodeMarks = {
  link: DotLink,
  bold: Bold,
  underline: Underline,
  italic: Italic,
  strike: Strike,
};

export const


below can be removed in production apps
// Useful for getting started locally with SQLite
async function findOrCreateTodosTable() {
  const result = await db.execute(
    "SELECT name FROM sqlite_master WHERE type='table' AND name='todos'",
  );

  if (!result || result?.rows?.length === 0) {
    await db.execute(
      "CREATE TABLE todos(id INTEGER PRIMARY KEY AUTOINCREMENT, description TEXT NOT NULL)",
    );
  }
}

export async function TodoList() {
  await findOrCreateTodosTable();
  const result = awa

 result.rows as unknown as TodoItem[];

  if (!result || result?.rows?.length === 0) return null;

  return rows.map((row, index) => (
    <Todo
      key={index}
      item={{
        id: row.id,
        description: row.description,
      }}
    />
  ));

it db.execute("SELECT * FROM todos");
  const rows =


iner 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 } 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];

&& (
            <HeroPost
              title={heroPost.title}
              coverImage={heroPost.coverImage}
              date={heroPost.date}
              author={heroPost.author}
              slug={heroPost.slug}
              excerpt={heroPost.exce

 const morePosts = allPosts.slice(1);
  return (
    <>
      <Layout>
        <Head>
          <title>{`Next.js Blog Example with ${CMS_NAME}`}</title>
        </Head>
        <Container>
          <Intro />
          {heroPost


URL } from "@/lib/constants";

export default function Intro() {
  return (

        Blog.

        A statically generated blog example using{" "}
        <a
          href="https://nextjs.org/"
          className="underline hover:tex

          Next.js
        </a>{" "}
        and{" "}
        <a
          href={CMS_URL}
          className="underline hover:text-success duration-200 transition-colors"
        >
          {CMS_NAME}
        </a>
        .
      </h4>
    </section>
  );


* @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,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,
      },
      fon


m";
import { Feature } from "./types";

export let metadata = {
  title: "Next.js and Redis Example",
  description: "Feature roadmap example with Next.js with Redis.",
};

function VercelLogo(props: React.SVGProps<SVGSVGElement>) {
  return (
    <svg
      aria-label="Vercel Logo"
      xmlns="http://www.w3.org/2000/svg"
      fill="none"
      viewBox="0 0 24 19"
      {...props}
    >
      <path
        clipRule="evenodd"
        d="M12.04 2L2.082 18H22L12.04 2z"
        fill="#000"
        fillRule="e

ength) {
      return [];
    }

    let multi = kv.multi();
    itemIds.forEach((id) => {
      multi.hgetall(`item:${id}`);
    });

    let items: Feature[] = await multi.exec();
    return items.map((item) => {
      return {
        ...item,
        s

venodd"
        stroke="#000"
        strokeWidth="1.5"
      />
    </svg>
  );
}

async function getFeatures() {
  try {
    let itemIds = await kv.zrange("items_by_score", 0, 100, {
      rev: true,
    });

    if (!itemIds.l


Container from "./container";
import { EXAMPLE_PATH } from "@/lib/constants";

export default function Footer() {
  return (

      <Container>

            Statically Generated with Next.js.

          <div className="f

r 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/$

lex 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 borde


 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

  </>
          ) : (
            <>
              The source code for this blog is{" "}
              <a
                href={`https://github.com/vercel/next.js/tree/canary/examples/${EXAMPLE_PATH}`}
                className="underline hover:text-succes

      href="/api/exit-preview"
                className="underline hover:text-cyan duration-200 transition-colors"
              >
                Click here
              </a>{" "}
              to exit preview mode.


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"

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/r

 />
      <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/


e: https://www.datocms.com/blog/offer-responsive-progressive-lqip-images-in-2020
const responsiveImageFragment = `
  fragment responsiveImageFragment on ResponsiveImage {
  srcSet
    webpSrcSet
    sizes
    src
    width
    height
    aspectRatio
    alt
    title
    bgColor
    base64
  }
`;

async function fetchAPI(query, { variables, preview } = {}) {
  const res = await fetch(API_URL + (preview ? "/preview" : ""), {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      A

 to fetch API");
  }
  return json.data;
}

export async function getPreviewPostBySlug(slug) {
  const data = await fetchAPI(
    `
    query PostBySlug($slug: String) {
      post(filter: {slug: {eq: $slug}}) {
        slug
      }
    }`,
    {
      pre

uthorization: `Bearer ${API_TOKEN}`,
    },
    body: JSON.stringify({
      query,
      variables,
    }),
  });

  const json = await res.json();
  if (json.errors) {
    console.error(json.errors);
    throw new Error("Failed


tar from "./avatar";
import Date from "./date";
import CoverImage from "./cover-image";
import Link from "next/link";

export default function PostPreview({
  title,
  coverImage,
  date,
  excerpt,
  author,
  slug,
}) {
  return (

        <CoverImage
          slug={slug}
          title={title}
          responsiveImage={coverImage.responsiveImage}
        />

        <Link href={`/posts/${slug}`} classNa

rline">
          {title}
        </Link>

        <Date dateString={date} />

{excerpt}

      <Avatar name={author.name} picture={author.pict


c function preview(req, res) {
  // Check the secret and next parameters
  // This secret should only be known to this API route and the CMS
  if (
    req.query.secret !== process.env.DATOCMS_PREVIEW_SECRET ||
    !req.query.slug
  ) {
    return res.status(401).json({ message: "Invalid token" });
  }

  // Fetch the headless CMS to check if the provided `slug` exists
  const post = await getPreviewPostBySlug(req.query.slug);

  // If the slug doesn't exist prevent preview mode from being enabled
  if (!po

valid slug" });
  }

  // Enable Draft Mode by setting the cookie
  res.setDraftMode({ enable: true });

  // 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.writ

st) {
    return res.status(401).json({ message: "In


  "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {
      container: {
        screens: {
          sm: "640px",
          md: "768px",
          lg: "1024px",
          xl: "1280px",
        },
      },
      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: {


 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

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

     href="/api/exit-preview"
                className="underline hover:text-cyan duration-200 transition-colors"
              >
                Click here
              </a>{" "}
              to exit preview mode.


mport Avatar from "./avatar";
import Date from "./date";
import CoverImage from "./cover-image";
import Link from "next/link";

export default function HeroPost({
  title,
  coverImage,
  date,
  excerpt,
  author,
  slug,
}) {
  return (

        <CoverImage
          title={title}
          responsiveImage={coverImage.responsiveImage}
          slug={slug}
        />

      <div className="md:grid md:grid-cols-2 md:gap-x-16 lg:gap-x-8 mb-20 md

            <Date dateString={date} />

{excerpt}

          <Avatar name={author.name} picture={author.picture} />

:mb-28">

            <Link href={`/posts/${slug}`} className="hover:underline">
              {title}
            </Link>


vatar";
import Date from "./date";
import CoverImage from "./cover-image";
import PostTitle from "./post-title";

export default function PostHeader({ title, coverImage, date, author }) {
  return (
    <>
      <PostTitle>{title}</PostTitle>

        <Avatar name={author.name} picture={author.picture} />

        <CoverImage
          title={title}
          responsiveImage={coverImage.responsiveImage}

-2xl mx-auto">

          <Avatar name={author.name} picture={author.picture} />

          <Date dateString={date} />

    </>

        />
      </div>
      <div className="max-w


orPage 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 "nex

?.slug) {
    return <ErrorPage statusCode={404} />;
  }
  return (
    <Layout preview={preview}>
      <Container>
        <Header />
        {router.isFallback ? (
          <PostTitle>Loading…</PostTitle>
        ) : (
          <>
            <article

t/head";
import { CMS_NAME } from "@/lib/constants";
import markdownToHtml from "@/lib/markdownToHtml";

export default function Post({ post, morePosts, preview }) {
  const router = useRouter();
  if (!router.isFallback && !post


bject} param1.variables - The variables to pass to the query
 * @param {Object} param1.preview - Indicate if the query should be previewed
 * @returns {Promise} - A promise that resolves to the result of the query
 */
async function fetchAPI(query, { variables } = { variables: null }) {
  const res = await fetch(
    process.env.NEXT_PUBLIC_DOTCMS_HOST + "/api/v1/graphql",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${process.env.DO

tch API");
  }

  return json.data;
}

/**
 * Get the correct type to filter post using preview flag
 *
 * @param preview
 * @returns {string}
 */
const showPreviewPosts = (preview) => {
  return preview === true
    ? "+working:true +deleted:false"
    :

TCMS_TOKEN}`,
      },
      body: JSON.stringify({
        query,
        variables,
      }),
    },
  );

  const json = await res.json();

  if (json.errors) {
    console.error(json.errors);
    throw new Error("Failed to fe


 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 }) {
  const heroPost = allPosts[0];
  const morePosts = allPosts.slice(1);
  return (
    <>
      <Layout>
        <Head>

ge={heroPost.coverImage}
              date={heroPost.date}
              author={heroPost.author}
              slug={heroPost.slug}
              excerpt={heroPost.excerpt}
            />
          )}
          {morePosts.length > 0 && <MoreStories posts

          <title>{`Next.js Blog Example with ${CMS_NAME}`}</title>
        </Head>
        <Container>
          <Intro />
          {heroPost && (
            <HeroPost
              title={heroPost.title}
              coverIma


 DotImage,
  Heading,
  ListItem,
  OrderedList,
  Paragraph,
  TextNode,
} from "./blocks";

/*
  dotCMS Block Editor is a new rich content editor that allows you to create your content as building blocks.

  More info: https://dotcms.com/docs/latest/block-editor
*/

export const ContentBlocks = ({ content }) => {
  return (
    <>
      {content?.map((data, index) => {
        switch (data.type) {
          case "paragraph":
            return (
              <Paragraph key={index}>
                <Conte

.content} />
              </Heading>
            );

          case "bulletList":
            return (
              <BulletList key={index}>
                <ContentBlocks content={data.content} />
              </BulletList>
            );

          ca

ntBlocks content={data.content} />
              </Paragraph>
            );
          case "heading":
            return (
              <Heading key={index} level={data.attrs.level}>
                <ContentBlocks content={data


Container from "./container";
import { EXAMPLE_PATH } from "@lib/constants";

export default function Footer() {
  return (

      <Container>

            Statically Generated with Next.js.

          <div className="fl

 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/${

ex 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


URL } from "@lib/constants";

export default function Intro() {
  return (

        Blog.

        A statically generated blog example using{" "}
        <a
          href="https://nextjs.org/"
          className="underline hover:text

         Next.js
        </a>{" "}
        and{" "}
        <a
          href={CMS_URL}
          className="underline hover:text-success duration-200 transition-colors"
        >
          {CMS_NAME}
        </a>
        .
      </h4>
    </section>
  );


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"

avicon.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/rs

/>
      <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/f


ort 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 (

        <CoverImage
          width={1200}
          height={600}
          title={title}
          slug={slug}
          src={coverImage.idPath}
          objectFit="cover"
          layout={"intrinsic"}

assName="mb-4 text-lg">
          <DateComponent dateString={date} />

      ) : null}

{excerpt}

      {author.length ? (
        <Avatar
          name={`${author[0].firstName} ${author[0

        />
      </div>
      <h3 className="mb-3 text-3xl leading-snug">
        <Link href={`/posts/${slug}`} className="hover:underline">
          {title}
        </Link>
      </h3>
      {date !== "now" ? (
        <div cl


 function preview(req, res) {
  const { secret, slug } = req.query;

  if (secret !== process.env.DOTCMS_PREVIEW_SECRET || !slug) {
    return res.status(401).json({ message: "Invalid token" });
  }

  // Fetch the headless CMS to check if the provided `slug` exists
  const post = await getPreviewPostBySlug(slug, true);

  // If the slug doesn't exist prevent preview mode from being enabled
  if (Object.keys(post.post).length < 1) {
    return res.status(401).json({ message: "Invalid slug" });
  }

  // Ena

ode({ enable: true });

  // Redirect to the path from the fetched post
  const url = `/posts/${post.post.urlTitle}`;
  res.setHeader("Content-Type", "text/html");
  res.write(
    `<!DOCTYPE html><html><head><meta http-equiv="Refresh" content="0; url=${ur

ble Draft Mode by setting the cookie
  res.setDraftM


ort { addTodo } from "./actions";

function Submit() {
  const { pending } = useFormStatus();

  return (
    <button type="submit" aria-disabled={pending} className="sr-only">
      Add
    </button>
  );
}

export function Form() {
  const formRef = useRef<HTMLFormElement>(null);

  formRef.current?.reset();

  return (
    <form
      action={async (formData) => {
        await addTodo(formData);
        formRef.current?.reset();
      }}
      className="rounded-md border border-gray-300 p-3 shadow-sm"

escription"
        name="description"
        placeholder="Insert new todo"
        className="w-full text-black outline-none"
        required
        aria-label="Description of todo"
        type="text"
        autoFocus
      />

      <Submit />
    <

      ref={formRef}
    >
      <input
        id="d


nk";
import Avatar from "@components/avatar";
import DateComponent from "@components/date";
import CoverImage from "@components/cover-image";
import cn from "classnames";

export default function HeroPost({
  title,
  coverImage,
  date,
  excerpt,
  author,
  slug,
}) {
  return (

        <CoverImage
          width={2000}
          height={1000}
          title={title}
          slug={slug}
          objectFit="cover"
          layout={"intrinsic"}

            <Link
              as={`/posts/${slug}`}
              href="/posts/[slug]"

     src={coverImage.idPath}
          alt={`Cover Image for ${title}`}
          className={cn("shadow-small", {
            "hover:shadow-medium transition-shadow duration-200": slug,
          })}
        />
      </div>


d from "next/head";
import ErrorPage from "next/error";
import Container from "@components/container";
import MoreStories from "@components/more-stories";
import Header from "@components/header";
import PostHeader from "@components/post-header";
import PostBody from "@components/post-body";
import SectionSeparator from "@components/section-separator";
import Layout from "@components/layout";
import PostTitle from "@components/post-title";
import { CMS_NAME } from "@lib/constants";
import { getAllPostsWithSl

title = `${
    post?.title || "dotcms"
  } | Next.js Blog Example with ${CMS_NAME}`;

  return (
    <Layout preview={preview}>
      <Container>
        <Header />
        {router.isFallback ? (
          <PostTitle>Loading…</PostTitle>
        ) : (

ug, getPostAndMorePosts } from "@lib/api";

export default function Post({ post, morePosts, preview }) {
  const router = useRouter();

  if (!router.isFallback && !post) {
    return <ErrorPage statusCode={404} />;
  }

  const


ContentBlocks } from "./content-blocks";
import DateComponent from "./date";
import Avatar from "./avatar";

export default function PostBody({ content }) {
  return (

        {content.author.length ? (
          <Avatar
            name={`${content.author[0].firstName} ${content.author[0].lastName}`}
            picture={content.author[0].profilePhoto}
          />
        ) : null}

      <d

gDate !== "now" ? (
          <div className="mb-6 text-lg">
            Posted <DateComponent dateString={content.postingDate} />
          </div>
        ) : null}
      </div>
      <ContentBlocks content={content.blogContent.json.content} />
    </div>

iv className="mb-6 text-lg">
        {content.postin


iner 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({ preview, allPosts }) {
  const heroPost = allPosts[0];
  const morePosts = allPosts.slice(1);
  const title = `Next.js Blog Example with ${CMS_NAM

eroPost.title}
              coverImage={heroPost.image}
              date={heroPost.postingDate}
              author={heroPost.author}
              slug={heroPost.urlTitle}
              excerpt={heroPost.teaser}
            />
          )}
          {

E}`;
  return (
    <>
      <Layout preview={preview}>
        <Head>
          <title>{title}</title>
        </Head>
        <Container>
          <Intro />
          {heroPost && (
            <HeroPost
              title={h


 sets a custom webpack configuration to use your Next.js app
// with Sentry.
// https://nextjs.org/docs/app/api-reference/config/next-config-js
// https://docs.sentry.io/platforms/javascript/guides/nextjs/

const { withSentryConfig } = require("@sentry/nextjs");

const moduleExports = {
  // Your existing module.exports
  reactStrictMode: true,

  sentry: {
    // Use `hidden-source-map` rather than `source-map` as the Webpack `devtool`
    // for client-side builds. (This will be the default starting in

    hideSourceMaps: true,
  },
};

// Make sure adding Sentry options is the last code to run before exporting, to
// ensure that your source maps include changes from all other Webpack plugins
module.exports = withSentryConfig(moduleExports, {
  // Additi

  // `@sentry/nextjs` version 8.0.0.) See
    // https://webpack.js.org/configuration/devtool/ and
    // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/#use-hidden-source-map
    // for more information.


 This page is loaded by Nextjs:
 *  - on the server, when data-fetching methods throw or reject
 *  - on the client, when `getInitialProps` throws or rejects
 *  - on the client, when a React lifecycle method throws or rejects, and it's
 *    caught by the built-in Nextjs error boundary
 *
 * See:
 *  - https://nextjs.org/docs/basic-features/data-fetching/overview
 *  - https://nextjs.org/docs/api-reference/data-fetching/get-initial-props
 *  - https://react.dev/reference/react/Component#catching-rendering-

mErrorComponent.getInitialProps = async (contextData) => {
  // In case this is running in a serverless function, await this in order to give Sentry
  // time to send the error before the lambda exits
  await Sentry.captureUnderscoreErrorException(contextD

errors-with-an-error-boundary
 */

import * as Sentry from "@sentry/nextjs";
import NextErrorComponent from "next/error";

const CustomErrorComponent = (props) => (
  <NextErrorComponent statusCode={props.statusCode} />
);

Custo


s.code}>npx @sentry/wizard -s -i nextjs

            By{" "}
            <Image
              src="/vercel.svg"
              alt="Vercel Logo"
              className={styles.vercelLogo}
              width={100}
              height={24}
              priority

height={37}
          priority
        />
        <div className={styles.thirteen}>
          <Image src="/thirteen.svg" alt="13" width={40} height={31} priority />
        </div>
      </div>
      <Image
        src="/sentry.svg"
        alt="Sentry Logo

        />
          </a>
        </div>
      </div>

      <div className={styles.center}>
        <Image
          className={styles.logo}
          src="/next.svg"
          alt="Next.js Logo"
          width={180}


 string,
): Promise<CmsPost[]> {
  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<string[]> {
  var query = `
        query {
            posts {
                itemDefaultUrl
            }
        }
    `;

  const

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,

 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_


r 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 (

        <CoverImage title={title} src={cove

     as={`/posts${slug}`}
              href="/posts[slug]"
              className="hover:underline"
            >
              {title}
            </Link>
          </h3>
          <div className="mb-4 md:mb-0 text-lg">
            <DateFormatter dateSt

rImage} slug={slug} />

            <Link


iner from "./container";
import cn from "classnames";
import { EXAMPLE_PATH } from "../lib/constants";

type Props = {
  preview?: boolean;
};

const Alert = ({ preview }: Props) => {
  return (
    <div
      className={cn("border-b", {
        "bg-neutral-800 border-neutral-800 text-white": preview,
        "bg-neutral-50 border-neutral-200": !preview,
      })}
    >
      <Container>
        <div className="py-2 text-center text-sm">
          {preview ? (
            <>
              This page is a pre

          to exit preview mode.
            </>
          ) : (
            <>
              The source code for this blog is{" "}
              <a
                href={`https://github.com/vercel/next.js/tree/canary/examples/${EXAMPLE_PATH}`}

view.{" "}
              <a
                href="/api/exit-preview"
                className="underline hover:text-teal-300 duration-200 transition-colors"
              >
                Click here
              </a>{" "}


tter";
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 (
    <>
      <PostTitle>{title}</PostTitle>

        <Avatar name={author.name} picture={author.picture} />

      <div className="mb-8 md:mb-16 s

rImage} />

          <Avatar name={author.name} picture={author.picture} />

          <DateFormatter

m:mx-0">
        <CoverImage title={title} src={cove


This file configures the initialization of Sentry on the browser.
// The config you add here will be used whenever a page is visited.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/

import * as Sentry from "@sentry/nextjs";

const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;

Sentry.init({
  dsn: SENTRY_DSN,
  // Adjust this value in production, or use tracesSampler for greater control
  tracesSampleRate: 1.0,
  // ...
  // Note: if you want to override the autom

 replaysSessionSampleRate: 0.1,

  // If the entire session is not sampled, use the below sample rate to sample
  // sessions when an error occurs.
  replaysOnErrorSampleRate: 1.0,

  integrations: [
    new Sentry.Replay({
      // Additional SDK configur

atic release value, do not set a
  // `release` value here - use the environment variable `SENTRY_RELEASE`, so
  // that it will also get attached to your source maps
  // in development and sample at a lower rate in production


er } from "next/router";
import Code from "../components/Code";
import PageLayout from "../components/PageLayout";

export default function About() {
  const t = useTranslations("About");
  const { locale } = useRouter();
  const intl = useIntl();
  const lastUpdated = new Date(2021, 0, 26, 17, 4, 45);

  return (
    <PageLayout title={t("title")}>

        {t("description", {
          locale,
          code: (children) => {children},
        })}

        {t("last

atedRelative: intl.formatRelativeTime(lastUpdated),
        })}
      </p>
    </PageLayout>
  );
}

export function getStaticProps({ locale }) {
  return {
    props: {
      messages: {
        ...require(`../messages/shared/${locale}.json`),
        ...

Updated", {
          lastUpdated,
          lastUpd


from "next/head";
import { CMS_NAME, HOME_OG_IMAGE_URL } from "../lib/constants";

const 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"
      />
      <

" />
      <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" hre

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


port PostPreview from "./post-preview";
import type Post from "../interfaces/post";

type Props = {
  posts: Post[];
};

const MoreStories = ({ posts }: Props) => {
  return (

        More Stories

        {posts.map((post) => (
          <PostPreview
            key={post.slug}

title}
            coverImage={post.coverImage}
            date={post.date}
            author={post.author}
            slug={post.slug}
            excerpt={post.excerpt}
          />
        ))}
      </div>
    </section>
  );
};

export default MoreS


 App({ Component, pageProps }) {
  return (
    <NextIntlProvider
      // To achieve consistent date, time and number formatting
      // across the app, you can define a set of global formats.
      formats={{
        dateTime: {
          short: {
            day: "numeric",
            month: "short",
            year: "numeric",
          },
        },
      }}
      messages={pageProps.messages}
      // Providing an explicit value for `now` ensures consistent formatting of
      // relative values re

now={new Date(pageProps.now)}
      // Also an explicit time zone is helpful to ensure dates render the
      // same way on the client as on the server, which might be located
      // in a different time zone.
      timeZone="Austria/Vienna"
    >

gardless of the server or client environment.


mport 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 (

        <CoverImage slug={slug} title={tit

</Link>

        <DateFormatter dateString={date} />

{excerpt}

      <Avatar name={author.name} picture={author.picture} />

le} src={coverImage} />
      </div>
      <h3 className="text-3xl mb-3 leading-snug">
        <Link
          as={`/posts${slug}`}
          href="/posts[slug]"
          className="hover:underline"
        >
          {title}


Container from "./container";
import { EXAMPLE_PATH } from "../lib/constants";

const Footer = () => {
  return (

      <Container>

            Statically Generated with Next.js.

          <div className="fl

 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/${

ex 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


orPage 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 "

k && !post?.slug) {
    return <ErrorPage statusCode={404} />;
  }
  return (
    <Layout preview={preview}>
      <Container>
        <Header />
        {router.isFallback ? (
          <PostTitle>Loading…</PostTitle>
        ) : (
          <>

../../interfaces/post";

type Props = {
  post: PostType;
  morePosts: PostType[];
  preview?: boolean;
};

export default function Post({ post, morePosts, preview }: Props) {
  const router = useRouter();
  if (!router.isFallbac


;

import algoliasearch from "algoliasearch/lite";
import type { Hit as AlgoliaHit } from "instantsearch.js";
import React from "react";
import {
  Configure,
  Highlight,
  Hits,
  Pagination,
  RefinementList,
  SearchBox,
} from "react-instantsearch";
import { InstantSearchNext } from "react-instantsearch-nextjs";

import { Panel } from "./Panel";

type HitProps = {
  hit: AlgoliaHit<{
    name: string;
    description: string;
    price: number;
  }>;
};

const APP_ID = "latency";
const API_KEY = "6be05

Hit-label" />
      ${hit.price}
    </>
  );
}

export default function Search() {
  return (
    <InstantSearchNext
      searchClient={searchClient}
      indexName={INDEX_NAME}
      routing
      future={{
        pr

76ff61c053d5f9a3225e2a90f76";
const INDEX_NAME = "instant_search";

const searchClient = algoliasearch(APP_ID, API_KEY);

function Hit({ hit }: HitProps) {
  return (
    <>
      <Highlight hit={hit} attribute="name" className="


okie,
  deleteCookie,
  hasCookie,
} from "cookies-next";

const Home = () => {
  const handleSetCookie = () => setCookie("client-cookie", "mock client value");
  const handleCheckCookie = () => console.log(hasCookie("client-cookie"));
  const handleGetCookie = () => console.log(getCookie("client-cookie"));
  const handleGetCookies = () => console.log(getCookies());
  const handleDeleteCookies = () => deleteCookie("client-cookie");

  return (

Next Cookies

      <button onClick={ha

<button onClick={handleCheckCookie}>Check Cookie</button>

      <button onClick={handleGetCookie}>Get Cookie</button>

      <button onClick={handleGetCookies}>Get All Cookies</button>

      <button onClick={handleDe

ndleSetCookie}>Set Cookie</button>
      <br />


"@clerk/nextjs";
import { useEffect, useState } from "react";
import styles from "../styles/Home.module.css";
import "../styles/prism.css";

declare global {
  interface Window {
    Prism: any;
  }
}

const apiSample = `import { auth } from "@clerk/nextjs";
import { NextResponse } from "next/server";

export async function GET(request: Request) {
  const { userId, sessionId } = auth()
  if(!sessionId) {
    return NextResponse.json({ id: null }, { status: 401 })
  }
  return NextResponse.json({ id: userId

);

  const makeRequest = async () => {
    setResponse("// Loading...");

    try {
      const res = await fetch("/api/getAuthenticatedUserId");
      const body = await res.json();
      setResponse(JSON.stringify(body, null, "  "));
    } catch (e) {

}, { status: 200 })
}`;

export const APIRequest = () => {
  useEffect(() => {
    if (window.Prism) {
      window.Prism.highlightAll();
    }
  });

  const [response, setResponse] = useState("// Click above to run the request"


test";
import path from "path";

// Use process.env.PORT by default and fallback to port 3000
const PORT = process.env.PORT || 3000;

// Set webServer.url and use.baseURL with the location of the WebServer respecting the correct set port
const baseURL = `http://localhost:${PORT}`;

// Reference: https://playwright.dev/docs/test-configuration
export default defineConfig({
  // Timeout per test
  timeout: 30 * 1000,
  // Test directory
  testDir: path.join(__dirname, "e2e"),
  // If a test fails, retry it add

advanced#launching-a-development-web-server-during-the-tests
  webServer: {
    command: "npm run dev",
    url: baseURL,
    timeout: 120 * 1000,
    reuseExistingServer: !process.env.CI,
  },

  use: {
    // Use baseURL so to make navigations relative.

itional 2 times
  retries: 2,
  // Artifacts folder where screenshots, videos, and traces are stored.
  outputDir: "test-results/",

  // Run your local dev server before starting the tests:
  // https://playwright.dev/docs/test-


* @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,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,
      },
      fon


om "@tryghost/content-api";
import { GHOST_API_URL_DEFAULT, GHOST_API_KEY_DEFAULT } from "./defaults.js";

const GHOST_API_URL = process.env.GHOST_API_URL || GHOST_API_URL_DEFAULT;
const GHOST_API_KEY = process.env.GHOST_API_KEY || GHOST_API_KEY_DEFAULT;

const api = new GhostContentAPI({
  url: GHOST_API_URL,
  key: GHOST_API_KEY,
  version: "v3.0",
});

const is404 = (error) => /not found/i.test(error.message);

export async function getPreviewPostBySlug(slug) {
  const params = {
    slug,
    fields: "s

ync function getAllPostsWithSlug() {
  const params = {
    fields: "slug",
    limit: "all",
  };
  const posts = await api.posts.browse(params);
  return posts;
}

export async function getAllPostsForHome(preview) {
  const params = {
    limit: "all",

lug",
    limit: "all",
  };

  try {
    const post = await api.posts.read(params);
    return post;
  } catch (error) {
    // Don't throw if an slug doesn't exist
    if (is404(error)) return;
    throw error;
  }
}

export as


ort Avatar from "./avatar";
import Date from "./date";
import CoverImage from "./cover-image";
import Link from "next/link";

export default function HeroPost({
  title,
  coverImage,
  date,
  excerpt,
  author,
  slug,
}) {
  return (

        <CoverImage
          title={title}
          url={coverImage}
          slug={slug}
          width={2000}
          height={1216}
        />

      <div className="md:grid md:grid-cols-2 md:gap-x-16 lg

            <Date dateString={date} />

{excerpt}

          <Avatar name={author.name} picture={a

:gap-x-8 mb-20 md:mb-28">

            <Link href={`/posts/${slug}`} className="hover:underline">
              {title}
            </Link>


react";
import { Environment, Network, RecordSource, Store } from "relay-runtime";

let relayEnvironment;

// Define a function that fetches the results of an operation (query/mutation/etc)
// and returns its results as a Promise
function fetchQuery(operation, variables, cacheConfig, uploadables) {
  return fetch(process.env.NEXT_PUBLIC_RELAY_ENDPOINT, {
    method: "POST",
    headers: {
      Accept: "application/json",
      "Content-Type": "application/json",
    }, // Add authentication and other heade

t({
    // Create a network layer from the fetch function
    network: Network.create(fetchQuery),
    store: new Store(new RecordSource()),
  });
}

export function initEnvironment(initialRecords) {
  // Create a network layer from the fetch function
  co

rs here
    body: JSON.stringify({
      query: operation.text, // GraphQL text from input
      variables,
    }),
  }).then((response) => response.json());
}

function createEnvironment(initialRecords) {
  return new Environmen