diff --git a/docs/api-reference/cli.md b/docs/api-reference/cli.md
index 20b36920d7bf..29e6aa8ea15c 100644
--- a/docs/api-reference/cli.md
+++ b/docs/api-reference/cli.md
@@ -39,6 +39,8 @@ NODE_OPTIONS='-r esm' next
NODE_OPTIONS='--inspect' next
```
+> Note: Running `next` without a command is the same as running `next dev`
+
## Build
`next build` creates an optimized production build of your application. The output displays information about each route.
diff --git a/docs/api-reference/next/image.md b/docs/api-reference/next/image.md
index 9f6db8cd9282..dedee45bfb57 100644
--- a/docs/api-reference/next/image.md
+++ b/docs/api-reference/next/image.md
@@ -50,9 +50,9 @@ When using an external URL, you must add it to
The `width` property can represent either the _rendered_ width or _original_ width in pixels, depending on the [`layout`](#layout) and [`sizes`](#sizes) properties.
-When using `layout="intrinsic"`, `layout="fixed"`, or `layout="raw"` without `sizes`, the `width` property represents the _rendered_ width in pixels, so it will affect how large the image appears.
+When using `layout="intrinsic"`, `layout="fixed"`, or `layout="raw"`, the `width` property represents the _rendered_ width in pixels, so it will affect how large the image appears.
-When using `layout="responsive"`, `layout="fill"`, or `layout="raw"` with `sizes`, the `width` property represents the _original_ width in pixels, so it will only affect the aspect ratio.
+When using `layout="responsive"`, `layout="fill"`, the `width` property represents the _original_ width in pixels, so it will only affect the aspect ratio.
The `width` property is required, except for [statically imported images](#local-images), or those with `layout="fill"`.
@@ -60,9 +60,9 @@ The `width` property is required, except for [statically imported images](#local
The `height` property can represent either the _rendered_ height or _original_ height in pixels, depending on the [`layout`](#layout) and [`sizes`](#sizes) properties.
-When using `layout="intrinsic"`, `layout="fixed"`, or `layout="raw"` without `sizes`, the `height` property represents the _rendered_ height in pixels, so it will affect how large the image appears.
+When using `layout="intrinsic"`, `layout="fixed"`, or `layout="raw"`, the `height` property represents the _rendered_ height in pixels, so it will affect how large the image appears.
-When using `layout="responsive"`, `layout="fill"`, or `layout="raw"` with `sizes`, the `height` property represents the _original_ height in pixels, so it will only affect the aspect ratio.
+When using `layout="responsive"`, `layout="fill"`, the `height` property represents the _original_ height in pixels, so it will only affect the aspect ratio.
The `height` property is required, except for [statically imported images](#local-images), or those with `layout="fill"`.
@@ -94,8 +94,7 @@ The layout behavior of the image as the viewport changes size.
- This is usually paired with the [`objectFit`](#objectFit) property.
- Ensure the parent element has `position: relative` in their stylesheet.
- When `raw`[\*](#experimental-raw-layout-mode), the image will be rendered as a single image element with no wrappers, sizers or other responsive behavior.
- - If your image styling will change the size of a `raw` image, you should include the `sizes` property for proper image serving. Otherwise your image will receive a fixed height and width.
- - The other layout modes are optimized for performance and should cover nearly all use cases. It is recommended to try to use those modes before using `raw`.
+ - If your image styling will change the size of a `raw` image, you should include the `sizes` property for proper image serving. Otherwise your image will be requested as though it has fixed width and height.
- [Demo background image](https://image-component.nextjs.gallery/background)
### loader
@@ -181,6 +180,8 @@ Allows [passing CSS styles](https://reactjs.org/docs/dom-elements.html#style) to
Note that all `layout` modes other than `"raw"`[\*](#experimental-raw-layout-mode) apply their own styles to the image element, and these automatic styles take precedence over the `style` prop.
+Also keep in mind that the required `width` and `height` props can interact with your styling. If you use styling to modify an image's `width`, you must set the `height="auto"` style as well, or your image will be distorted.
+
### objectFit
Defines how the image will fit into its parent container when using `layout="fill"`.
@@ -493,10 +494,6 @@ module.exports = {
}
```
-> Note on CLS with `layout="raw"`:
-> It is possible to cause [layout shift](https://web.dev/cls/) with the image component in `raw` mode. If you include a `sizes` property, the image component will not pass `height` and `width` attributes to the image, to allow you to apply your own responsive sizing.
-> An [aspect-ratio](https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-ratio) style property is automatically applied to prevent layout shift, but this won't apply on [older browsers](https://caniuse.com/mdn-css_properties_aspect-ratio).
-
### Animated Images
The default [loader](#loader) will automatically bypass Image Optimization for animated images and serve the image as-is.
diff --git a/docs/basic-features/data-fetching/get-server-side-props.md b/docs/basic-features/data-fetching/get-server-side-props.md
index de9bda3cd84d..2470a8e23647 100644
--- a/docs/basic-features/data-fetching/get-server-side-props.md
+++ b/docs/basic-features/data-fetching/get-server-side-props.md
@@ -74,6 +74,32 @@ export async function getServerSideProps() {
export default Page
```
+## Caching with Server-Side Rendering (SSR)
+
+You can use caching headers (`Cache-Control`) inside `getServerSideProps` to cache dynamic responses. For example, using [`stale-while-revalidate`](https://web.dev/stale-while-revalidate/).
+
+```jsx
+// This value is considered fresh for ten seconds (s-maxage=10).
+// If a request is repeated within the next 10 seconds, the previously
+// cached value will still be fresh. If the request is repeated before 59 seconds,
+// the cached value will be stale but still render (stale-while-revalidate=59).
+//
+// In the background, a revalidation request will be made to populate the cache
+// with a fresh value. If you refresh the page, you will see the new value.
+export async function getServerSideProps({ req, res }) {
+ res.setHeader(
+ 'Cache-Control',
+ 'public, s-maxage=10, stale-while-revalidate=59'
+ )
+
+ return {
+ props: {},
+ }
+}
+```
+
+Learn more about [caching](/docs/going-to-production.md).
+
## Does getServerSideProps render an error page
If an error is thrown inside `getServerSideProps`, it will show the `pages/500.js` file. Check out the documentation for [500 page](/docs/advanced-features/custom-error-page#500-page) to learn more on how to create it. During development this file will not be used and the dev overlay will be shown instead.
diff --git a/docs/basic-features/data-fetching/incremental-static-regeneration.md b/docs/basic-features/data-fetching/incremental-static-regeneration.md
index fa0a1b350e8d..85478a77556a 100644
--- a/docs/basic-features/data-fetching/incremental-static-regeneration.md
+++ b/docs/basic-features/data-fetching/incremental-static-regeneration.md
@@ -171,6 +171,29 @@ export async function getStaticProps() {
}
```
+## Self-hosting ISR
+
+Incremental Static Regeneration (ISR) works on [self-hosted Next.js sites](/docs/deployment.md#self-hosting) out of the box when you use `next start`.
+
+You can use this approach when deploying to container orchestrators such as [Kubernetes](https://kubernetes.io/) or [HashiCorp Nomad](https://www.nomadproject.io/). By default, generated assets will be stored in-memory on each pod. This means that each pod will have its own copy of the static files. Stale data may be shown until that specific pod is hit by a request.
+
+To ensure consistency across all pods, you can disable in-memory caching. This will inform the Next.js server to only leverage assets generated by ISR in the file system.
+
+You can use a shared network mount in your Kubernetes pods (or similar setup) to reuse the same file-system cache between different containers. By sharing the same mount, the `.next` folder which contains the `next/image` cache will also be shared and re-used.
+
+To disable in-memory caching, set `isrMemoryCacheSize` to `0` in your `next.config.js` file:
+
+```js
+module.exports = {
+ experimental: {
+ // Defaults to 50MB
+ isrMemoryCacheSize: 0,
+ },
+}
+```
+
+> **Note:** You might need to consider a race condition between multiple pods trying to update the cache at the same time, depending on how your shared mount is configured.
+
## Related
For more information on what to do next, we recommend the following sections:
diff --git a/docs/basic-features/font-optimization.md b/docs/basic-features/font-optimization.md
index 217267338e5a..bcd1498072fa 100644
--- a/docs/basic-features/font-optimization.md
+++ b/docs/basic-features/font-optimization.md
@@ -16,6 +16,7 @@ By default, Next.js will automatically inline font CSS at build time, eliminatin
/>
// After
+
diff --git a/docs/basic-features/script.md b/docs/basic-features/script.md
index ac6999a654dd..cb3905ce4800 100644
--- a/docs/basic-features/script.md
+++ b/docs/basic-features/script.md
@@ -243,10 +243,7 @@ Or by using the `dangerouslySetInnerHTML` property:
/>
```
-There are two limitations to be aware of when using the Script component for inline scripts:
-
-- Only the `afterInteractive` and `lazyOnload` strategies can be used. The `beforeInteractive` loading strategy injects the contents of an external script into the initial HTML response. Inline scripts already do this, which is why **the `beforeInteractive` strategy cannot be used with inline scripts.**
-- An `id` attribute must be defined in order for Next.js to track and optimize the script
+The `id` property is required for **inline scripts** in order for Next.js to track and optimize the script.
### Executing Code After Loading (`onLoad`)
diff --git a/errors/invalid-script.md b/errors/invalid-script.md
new file mode 100644
index 000000000000..f919a25a0087
--- /dev/null
+++ b/errors/invalid-script.md
@@ -0,0 +1,38 @@
+# Invalid Script
+
+#### Why This Error Occurred
+
+Somewhere in your application, you are using the `next/script` component without including an inline script or `src` attribute.
+
+#### Possible Ways to Fix It
+
+Look for any usage of the `next/script` component and make sure that `src` is provided or an inline script is used.
+
+**Compatible `src` attribute**
+
+```jsx
+
+```
+
+**Compatible inline script with curly braces**
+
+```jsx
+
+```
+
+**Compatible inline script with `dangerouslySetInnerHtml`**
+
+```jsx
+
+```
+
+### Useful Links
+
+- [Script Component in Documentation](https://nextjs.org/docs/basic-features/script)
diff --git a/errors/manifest.json b/errors/manifest.json
index 6141e5076ce8..8e5375a6d5a1 100644
--- a/errors/manifest.json
+++ b/errors/manifest.json
@@ -657,6 +657,10 @@
{
"title": "no-assign-module-variable",
"path": "/errors/no-assign-module-variable.md"
+ },
+ {
+ "title": "invalid-script",
+ "path": "/errors/invalid-script.md"
}
]
}
diff --git a/examples/with-chakra-ui-typescript/README.md b/examples/with-chakra-ui-typescript/README.md
index ec21712d4005..f9c22dffe952 100644
--- a/examples/with-chakra-ui-typescript/README.md
+++ b/examples/with-chakra-ui-typescript/README.md
@@ -1,35 +1,3 @@
-# Example app with [chakra-ui](https://github.com/chakra-ui/chakra-ui) and TypeScript
+## Deprecated
-This example features how to use [chakra-ui](https://github.com/chakra-ui/chakra-ui) as the component library within a Next.js app with TypeScript.
-
-Next.js and chakra-ui have built-in TypeScript declarations, so we'll get autocompletion for their modules straight away.
-
-We are connecting the Next.js `_app.js` with `chakra-ui`'s Provider and theme so the pages can have app-wide dark/light mode. We are also creating some components which shows the usage of `chakra-ui`'s style props.
-
-## Deploy your own
-
-Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-chakra-ui-typescript)
-
-[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-chakra-ui-typescript&project-name=with-chakra-ui-typescript&repository-name=with-chakra-ui-typescript)
-
-## How to use
-
-### Using `create-next-app`
-
-Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
-
-```bash
-npx create-next-app --example with-chakra-ui-typescript with-chakra-ui-typescript-app
-# or
-yarn create next-app --example with-chakra-ui-typescript with-chakra-ui-typescript-app
-# or
-pnpm create next-app -- --example with-chakra-ui-typescript with-chakra-ui-typescript-app
-```
-
-Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)).
-
-## Notes
-
-Chakra has supported Gradients and RTL in `v1.1`. To utilize RTL, [add RTL direction and swap](https://chakra-ui.com/docs/features/rtl-support).
-
-If you don't have multi-direction app, you should make `` inside `_document.ts`.
+The main [`with-chakra-ui`](../with-chakra-ui) example has been refactored to use TypeScript, so this example is deprecated.
diff --git a/examples/with-chakra-ui-typescript/package.json b/examples/with-chakra-ui-typescript/package.json
deleted file mode 100644
index 5bbac2940341..000000000000
--- a/examples/with-chakra-ui-typescript/package.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "private": true,
- "scripts": {
- "dev": "next",
- "build": "next build",
- "start": "next start"
- },
- "dependencies": {
- "@chakra-ui/icons": "^1.0.5",
- "@chakra-ui/react": "^1.4.2",
- "@chakra-ui/theme-tools": "1.1.2",
- "@emotion/react": "11.1.5",
- "@emotion/styled": "11.1.5",
- "framer-motion": "^4.0.3",
- "next": "latest",
- "react": "^17.0.2",
- "react-dom": "^17.0.2"
- },
- "devDependencies": {
- "@types/node": "^14.6.0",
- "@types/react": "^17.0.3",
- "@types/react-dom": "^17.0.3",
- "typescript": "4.3.2"
- }
-}
diff --git a/examples/with-chakra-ui-typescript/src/components/CTA.tsx b/examples/with-chakra-ui-typescript/src/components/CTA.tsx
deleted file mode 100644
index 35f9fc179a5a..000000000000
--- a/examples/with-chakra-ui-typescript/src/components/CTA.tsx
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Link as ChakraLink, Button } from '@chakra-ui/react'
-
-import { Container } from './Container'
-
-export const CTA = () => (
-
-
-
-
-
-
-
-
-
-)
diff --git a/examples/with-chakra-ui-typescript/src/components/Container.tsx b/examples/with-chakra-ui-typescript/src/components/Container.tsx
deleted file mode 100644
index acedb42afc99..000000000000
--- a/examples/with-chakra-ui-typescript/src/components/Container.tsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Flex, useColorMode, FlexProps } from '@chakra-ui/react'
-
-export const Container = (props: FlexProps) => {
- const { colorMode } = useColorMode()
-
- const bgColor = { light: 'gray.50', dark: 'gray.900' }
-
- const color = { light: 'black', dark: 'white' }
- return (
-
- )
-}
diff --git a/examples/with-chakra-ui-typescript/src/components/DarkModeSwitch.tsx b/examples/with-chakra-ui-typescript/src/components/DarkModeSwitch.tsx
deleted file mode 100644
index 7edd444801c9..000000000000
--- a/examples/with-chakra-ui-typescript/src/components/DarkModeSwitch.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-import { useColorMode, Switch } from '@chakra-ui/react'
-
-export const DarkModeSwitch = () => {
- const { colorMode, toggleColorMode } = useColorMode()
- const isDark = colorMode === 'dark'
- return (
-
- )
-}
diff --git a/examples/with-chakra-ui/README.md b/examples/with-chakra-ui/README.md
index 3c4630663289..183ff659fed9 100644
--- a/examples/with-chakra-ui/README.md
+++ b/examples/with-chakra-ui/README.md
@@ -1,17 +1,21 @@
-# Example app with [chakra-ui](https://github.com/chakra-ui/chakra-ui)
+# Example app with [chakra-ui](https://github.com/chakra-ui/chakra-ui) and TypeScript
-This example features how to use [chakra-ui](https://github.com/chakra-ui/chakra-ui) as the component library within a Next.js app.
+This example features how to use [chakra-ui](https://github.com/chakra-ui/chakra-ui) as the component library within a Next.js app with TypeScript.
-We are connecting the Next.js `_app.js` with `chakra-ui`'s Theme and ColorMode containers so the pages can have app-wide dark/light mode. We are also creating some components which shows the usage of `chakra-ui`'s style props.
+Next.js and chakra-ui have built-in TypeScript declarations, so we'll get autocompletion for their modules straight away.
+
+We are connecting the Next.js `_app.js` with `chakra-ui`'s Provider and theme so the pages can have app-wide dark/light mode. We are also creating some components which shows the usage of `chakra-ui`'s style props.
## Deploy your own
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-chakra-ui)
-[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-chakra-ui&project-name=with-chakra-ui&repository-name=with-chakra-ui)
+[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-chakra-ui-typescript&project-name=with-chakra-ui&repository-name=with-chakra-ui)
## How to use
+### Using `create-next-app`
+
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
```bash
@@ -28,4 +32,4 @@ Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&ut
Chakra has supported Gradients and RTL in `v1.1`. To utilize RTL, [add RTL direction and swap](https://chakra-ui.com/docs/features/rtl-support).
-If you don't have multi-direction app, you should make `` inside `_document.js`.
+If you don't have multi-direction app, you should make `` inside `_document.ts`.
diff --git a/examples/with-chakra-ui-typescript/next-env.d.ts b/examples/with-chakra-ui/next-env.d.ts
similarity index 100%
rename from examples/with-chakra-ui-typescript/next-env.d.ts
rename to examples/with-chakra-ui/next-env.d.ts
diff --git a/examples/with-chakra-ui/package.json b/examples/with-chakra-ui/package.json
index 55f53efc17a9..aa973b56cc55 100644
--- a/examples/with-chakra-ui/package.json
+++ b/examples/with-chakra-ui/package.json
@@ -1,18 +1,24 @@
{
"private": true,
"scripts": {
- "dev": "next dev",
+ "dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
- "@chakra-ui/icons": "^1.0.0",
- "@chakra-ui/react": "^1.4.2",
- "@emotion/react": "^11.0.0",
- "@emotion/styled": "^11.0.0",
- "framer-motion": "^4.0.3",
+ "@chakra-ui/icons": "^1.1.7",
+ "@chakra-ui/react": "1.8.8",
+ "@emotion/react": "^11",
+ "@emotion/styled": "^11",
+ "framer-motion": "^6",
"next": "latest",
"react": "^17.0.2",
"react-dom": "^17.0.2"
+ },
+ "devDependencies": {
+ "@types/node": "^14.6.0",
+ "@types/react": "^17.0.3",
+ "@types/react-dom": "^17.0.3",
+ "typescript": "4.3.2"
}
}
diff --git a/examples/with-chakra-ui/src/components/CTA.js b/examples/with-chakra-ui/src/components/CTA.js
deleted file mode 100644
index 8967493c3986..000000000000
--- a/examples/with-chakra-ui/src/components/CTA.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Link as ChakraLink, Button } from '@chakra-ui/react'
-
-import { Container } from './Container'
-
-export const CTA = () => (
-
-
-
-
-
-
-
-
-
-)
diff --git a/examples/with-chakra-ui/src/components/CTA.tsx b/examples/with-chakra-ui/src/components/CTA.tsx
new file mode 100644
index 000000000000..9af7f683fae0
--- /dev/null
+++ b/examples/with-chakra-ui/src/components/CTA.tsx
@@ -0,0 +1,41 @@
+import { Link as ChakraLink, Button } from '@chakra-ui/react'
+
+import { Container } from './Container'
+
+export const CTA = () => (
+
+
+
+
+)
diff --git a/examples/with-chakra-ui/src/components/Container.js b/examples/with-chakra-ui/src/components/Container.js
deleted file mode 100644
index 57b73e441954..000000000000
--- a/examples/with-chakra-ui/src/components/Container.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import { Flex, useColorMode } from '@chakra-ui/react'
-
-export const Container = (props) => {
- const { colorMode } = useColorMode()
-
- const bgColor = { light: 'gray.50', dark: 'gray.900' }
-
- const color = { light: 'black', dark: 'white' }
- return (
-
- )
-}
diff --git a/examples/with-chakra-ui/src/components/Container.tsx b/examples/with-chakra-ui/src/components/Container.tsx
new file mode 100644
index 000000000000..1ee74495aa6a
--- /dev/null
+++ b/examples/with-chakra-ui/src/components/Container.tsx
@@ -0,0 +1,17 @@
+import { Flex, FlexProps } from '@chakra-ui/react'
+
+export const Container = (props: FlexProps) => (
+
+)
diff --git a/examples/with-chakra-ui/src/components/DarkModeSwitch.js b/examples/with-chakra-ui/src/components/DarkModeSwitch.js
deleted file mode 100644
index 7edd444801c9..000000000000
--- a/examples/with-chakra-ui/src/components/DarkModeSwitch.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { useColorMode, Switch } from '@chakra-ui/react'
-
-export const DarkModeSwitch = () => {
- const { colorMode, toggleColorMode } = useColorMode()
- const isDark = colorMode === 'dark'
- return (
-
- )
-}
diff --git a/examples/with-chakra-ui/src/components/DarkModeSwitch.tsx b/examples/with-chakra-ui/src/components/DarkModeSwitch.tsx
new file mode 100644
index 000000000000..4e91c3b624ba
--- /dev/null
+++ b/examples/with-chakra-ui/src/components/DarkModeSwitch.tsx
@@ -0,0 +1,18 @@
+import { useColorMode, IconButton } from '@chakra-ui/react'
+import { SunIcon, MoonIcon } from '@chakra-ui/icons'
+
+export const DarkModeSwitch = () => {
+ const { colorMode, toggleColorMode } = useColorMode()
+ const isDark = colorMode === 'dark'
+ return (
+ : }
+ aria-label="Toggle Theme"
+ colorScheme="green"
+ onClick={toggleColorMode}
+ />
+ )
+}
diff --git a/examples/with-chakra-ui/src/components/Footer.js b/examples/with-chakra-ui/src/components/Footer.js
deleted file mode 100644
index 3b254626539d..000000000000
--- a/examples/with-chakra-ui/src/components/Footer.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import { Flex } from '@chakra-ui/react'
-
-export const Footer = (props) =>
diff --git a/examples/with-chakra-ui-typescript/src/components/Footer.tsx b/examples/with-chakra-ui/src/components/Footer.tsx
similarity index 100%
rename from examples/with-chakra-ui-typescript/src/components/Footer.tsx
rename to examples/with-chakra-ui/src/components/Footer.tsx
diff --git a/examples/with-chakra-ui/src/components/Hero.js b/examples/with-chakra-ui/src/components/Hero.js
deleted file mode 100644
index bf4d104cd237..000000000000
--- a/examples/with-chakra-ui/src/components/Hero.js
+++ /dev/null
@@ -1,17 +0,0 @@
-import { Flex, Heading } from '@chakra-ui/react'
-
-export const Hero = ({ title }) => (
-
-
- {title}
-
-
-)
-
-Hero.defaultProps = {
- title: 'with-chakra-ui',
-}
diff --git a/examples/with-chakra-ui-typescript/src/components/Hero.tsx b/examples/with-chakra-ui/src/components/Hero.tsx
similarity index 83%
rename from examples/with-chakra-ui-typescript/src/components/Hero.tsx
rename to examples/with-chakra-ui/src/components/Hero.tsx
index d10435e5526f..3ec7364c3197 100644
--- a/examples/with-chakra-ui-typescript/src/components/Hero.tsx
+++ b/examples/with-chakra-ui/src/components/Hero.tsx
@@ -5,7 +5,7 @@ export const Hero = ({ title }: { title: string }) => (
justifyContent="center"
alignItems="center"
height="100vh"
- bgGradient="linear(to-l, #7928CA, #FF0080)"
+ bgGradient="linear(to-l, heroGradientStart, heroGradientEnd)"
bgClip="text"
>
{title}
diff --git a/examples/with-chakra-ui/src/components/Main.js b/examples/with-chakra-ui/src/components/Main.js
deleted file mode 100644
index a89329e53d7a..000000000000
--- a/examples/with-chakra-ui/src/components/Main.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import { Stack } from '@chakra-ui/react'
-
-export const Main = (props) => (
-
-)
diff --git a/examples/with-chakra-ui-typescript/src/components/Main.tsx b/examples/with-chakra-ui/src/components/Main.tsx
similarity index 100%
rename from examples/with-chakra-ui-typescript/src/components/Main.tsx
rename to examples/with-chakra-ui/src/components/Main.tsx
diff --git a/examples/with-chakra-ui/src/pages/_app.js b/examples/with-chakra-ui/src/pages/_app.js
deleted file mode 100644
index 120241b21fb5..000000000000
--- a/examples/with-chakra-ui/src/pages/_app.js
+++ /dev/null
@@ -1,19 +0,0 @@
-import { ChakraProvider, ColorModeProvider } from '@chakra-ui/react'
-
-import theme from '../theme'
-
-function MyApp({ Component, pageProps }) {
- return (
-
-
-
-
-
- )
-}
-
-export default MyApp
diff --git a/examples/with-chakra-ui-typescript/src/pages/_app.tsx b/examples/with-chakra-ui/src/pages/_app.tsx
similarity index 100%
rename from examples/with-chakra-ui-typescript/src/pages/_app.tsx
rename to examples/with-chakra-ui/src/pages/_app.tsx
diff --git a/examples/with-chakra-ui/src/pages/_document.js b/examples/with-chakra-ui/src/pages/_document.js
deleted file mode 100644
index 2b8b5740baa4..000000000000
--- a/examples/with-chakra-ui/src/pages/_document.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import NextDocument, { Html, Head, Main, NextScript } from 'next/document'
-import { ColorModeScript } from '@chakra-ui/react'
-
-export default class Document extends NextDocument {
- render() {
- return (
-
-
- {/* Make Color mode to persists when you refresh the page. */}
-
-
-
-
-
- )
- }
-}
diff --git a/examples/with-chakra-ui-typescript/src/pages/_document.tsx b/examples/with-chakra-ui/src/pages/_document.tsx
similarity index 100%
rename from examples/with-chakra-ui-typescript/src/pages/_document.tsx
rename to examples/with-chakra-ui/src/pages/_document.tsx
diff --git a/examples/with-chakra-ui/src/pages/index.js b/examples/with-chakra-ui/src/pages/index.js
deleted file mode 100644
index b3e22de84965..000000000000
--- a/examples/with-chakra-ui/src/pages/index.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import {
- Link as ChakraLink,
- Text,
- Code,
- List,
- ListIcon,
- ListItem,
-} from '@chakra-ui/react'
-import { CheckCircleIcon, LinkIcon } from '@chakra-ui/icons'
-import { Hero } from '../components/Hero'
-import { Container } from '../components/Container'
-import { Main } from '../components/Main'
-import { DarkModeSwitch } from '../components/DarkModeSwitch'
-import { CTA } from '../components/CTA'
-import { Footer } from '../components/Footer'
-
-const Index = () => (
-
-
-
-
- Example repository of Next.js + chakra-ui.
-
-
-
-
-
-
- Chakra UI
-
-
-
-
-
- Next.js
-
-
-
-
-
-
-
-
-
-)
-
-export default Index
diff --git a/examples/with-chakra-ui-typescript/src/pages/index.tsx b/examples/with-chakra-ui/src/pages/index.tsx
similarity index 95%
rename from examples/with-chakra-ui-typescript/src/pages/index.tsx
rename to examples/with-chakra-ui/src/pages/index.tsx
index d20edf24bf01..2cb151cd990e 100644
--- a/examples/with-chakra-ui-typescript/src/pages/index.tsx
+++ b/examples/with-chakra-ui/src/pages/index.tsx
@@ -19,12 +19,12 @@ const Index = () => (
-
+
Example repository of Next.js + chakra-ui +{' '}
TypeScript.
-
+
-
-
-
- ),
- viewBox: '0 0 3000 3163',
- },
- },
-})
-
-export default theme
diff --git a/examples/with-chakra-ui-typescript/src/theme.tsx b/examples/with-chakra-ui/src/theme.tsx
similarity index 51%
rename from examples/with-chakra-ui-typescript/src/theme.tsx
rename to examples/with-chakra-ui/src/theme.tsx
index 880e01bd16a3..c621d5d4e959 100644
--- a/examples/with-chakra-ui-typescript/src/theme.tsx
+++ b/examples/with-chakra-ui/src/theme.tsx
@@ -11,6 +11,25 @@ const breakpoints = createBreakpoints({
})
const theme = extendTheme({
+ semanticTokens: {
+ colors: {
+ text: {
+ default: '#16161D',
+ _dark: '#ade3b8',
+ },
+ heroGradientStart: {
+ default: '#7928CA',
+ _dark: '#e3a7f9',
+ },
+ heroGradientEnd: {
+ default: '#FF0080',
+ _dark: '#fbec8f',
+ },
+ },
+ radii: {
+ button: '12px',
+ },
+ },
colors: {
black: '#16161D',
},
diff --git a/examples/with-chakra-ui-typescript/tsconfig.json b/examples/with-chakra-ui/tsconfig.json
similarity index 100%
rename from examples/with-chakra-ui-typescript/tsconfig.json
rename to examples/with-chakra-ui/tsconfig.json
diff --git a/examples/with-edgedb/.eslintignore b/examples/with-edgedb/.eslintignore
new file mode 100644
index 000000000000..1749e6c3ad9b
--- /dev/null
+++ b/examples/with-edgedb/.eslintignore
@@ -0,0 +1 @@
+dbschema/edgeql-js
\ No newline at end of file
diff --git a/examples/with-chakra-ui-typescript/.gitignore b/examples/with-edgedb/.gitignore
similarity index 89%
rename from examples/with-chakra-ui-typescript/.gitignore
rename to examples/with-edgedb/.gitignore
index 1437c53f70bc..0256922fe850 100644
--- a/examples/with-chakra-ui-typescript/.gitignore
+++ b/examples/with-edgedb/.gitignore
@@ -17,6 +17,7 @@
# misc
.DS_Store
+.vscode
*.pem
# debug
@@ -32,3 +33,6 @@ yarn-error.log*
# vercel
.vercel
+
+# query builder
+dbschema/edgeql-js
diff --git a/examples/with-edgedb/README.md b/examples/with-edgedb/README.md
new file mode 100644
index 000000000000..16ca965307e2
--- /dev/null
+++ b/examples/with-edgedb/README.md
@@ -0,0 +1,150 @@
+# Full-stack EdgeDB + Next.js application
+
+A simple blog application built with Next.js, TypeScript, [React](https://reactjs.org/), and [EdgeDB](https://www.edgedb.com/docs) on the backend.
+
+## Deploy your own
+
+Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example):
+
+[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-edgedb&project-name=with-edgedb&repository-name=with-edgedb&env=EDGEDB_DSN)
+
+## How to use
+
+### Download the example project
+
+Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init) or [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/) to bootstrap the example:
+
+```bash
+npx create-next-app --example with-edgedb with-edgedb-app
+# or
+yarn create next-app --example with-edgedb with-edgedb-app
+# or
+pnpm create next-app -- --example with-edgedb with-edgedb-app
+```
+
+Then `cd` into the created directory.
+
+```bash
+$ cd with-edgedb-app
+```
+
+### Install the CLI
+
+First install the EdgeDB CLI if you haven't already.
+
+```bash
+# macOS/Linux
+$ curl --proto '=https' --tlsv1.2 -sSf https://sh.edgedb.com | sh
+
+# Windows (Powershell)
+$ iwr https://ps1.edgedb.com -useb | iex
+```
+
+### Initialize the EdgeDB project
+
+Initialize the project with the following CLI command:
+
+```bash
+$ edgedb project init
+```
+
+After you follow the prompts, this command will spin up a local EdgeDB instance and apply all the migrations inside `dbschema/migrations`. Now that the project is initialized, all EdgeDB clients initialized inside the project directory will connect to this instance automatically—no need for environment variables or hard-coded configuration. ([Read more about projects here.](https://www.edgedb.com/docs/guides/projects))
+
+### Install dependencies
+
+Install npm dependencies:
+
+```bash
+$ npm install
+# or
+$ yarn
+```
+
+### Generate the query builder
+
+This project uses the EdgeQL query builder for TypeScript. This tool can express any EdgeQL query in a code-first way and infers a static return type. Generate it with the following command:
+
+```bash
+$ npx edgeql-js
+```
+
+The query builder consists of several files that are generated into the `dbschema/edgeql-js` directory. Import it like so:
+
+```ts
+import e from './dbschema/edgeql-js'
+```
+
+### Seed the database
+
+```bash
+$ npx ts-node seed.ts
+```
+
+### Start the app
+
+```bash
+$ yarn dev
+```
+
+The application should now be running on http://localhost:3000.
+
+## Notes
+
+#### packages structure
+
+- `/`: See all published posts
+- `/drafts`: See all drafts
+- `/create`: Form to create new draft
+- `/blog/:id`: See either an edit page or a published post, depending on the publish status of the post.
+
+#### API structure
+
+- `POST /api/post`: Create a new post
+ - Body: `{title: string; content: string; authorName: string}`
+- `PATCH /api/post/:id`: Update a post by `id`
+ - Body: `{title?: string; content?: string;}`
+- `PUT /api/publish/:id`: Publish a post by `id`
+- `DELETE /api/post/:id`: Delete a post by `id`
+
+## Evolving the app
+
+Evolving the application typically requires three steps:
+
+1. Update the schema in `dbschema/default.esdl`
+2. Generate a new migration with `edgedb migration create`
+3. Apply the migration with `edgedb migrate`
+4. Regenerate the query builder with `npx edgeql-js`
+5. Update the application code, as needed.
+
+## Deployment
+
+To deploy this application, deploy EdgeDB to your preferred cloud provider:
+
+- [AWS](https://www.edgedb.com/docs/guides/deployment/aws_aurora_ecs)
+- [Google Cloud](https://www.edgedb.com/docs/guides/deployment/gcp)
+- [Azure](https://www.edgedb.com/docs/guides/deployment/azure_flexibleserver)
+- [DigitalOcean](https://www.edgedb.com/docs/guides/deployment/digitalocean)
+- [Fly.io](https://www.edgedb.com/docs/guides/deployment/fly_io)
+- [Docker](https://www.edgedb.com/docs/guides/deployment/docker) (cloud-agnostic)
+
+Then:
+
+1. Find your instance's DSN (AKA connection string). The exact instructions for this depend on which cloud you are deploying to.
+
+2. Use this DSN to migrate your remote instance to the latest schema. Run this command from inside your project directory.
+
+```
+edgedb migrate --dsn --tls-security insecure
+```
+
+You have to disable TLS checks with `--tls-security insecure`. All EdgeDB instances use TLS by default, but configuring it is out of scope of this project.
+
+3. Deploy this app to Vercel with the button above. You'll be prompted to provide a value for `EDGEDB_DSN`, the value from the previous step.
+
+4. Open the application at the deployment URL supplied by Vercel.
+
+## Next steps
+
+- Check out the [EdgeDB docs](https://www.edgedb.com/docs)
+- Join the EdgeDB [Discord server](https://edgedb.com/p/discord)
+- Check out the code on [GitHub](https://github.com/edgedb/edgedb)
diff --git a/examples/with-edgedb/client.ts b/examples/with-edgedb/client.ts
new file mode 100644
index 000000000000..4cb2a65302eb
--- /dev/null
+++ b/examples/with-edgedb/client.ts
@@ -0,0 +1,9 @@
+import { createClient } from 'edgedb'
+import e from './dbschema/edgeql-js'
+
+// reads value of EDGEDB_DSN automatically
+export const client = createClient({
+ // TLS configuration is beyond the scope of this example project
+ tlsSecurity: 'insecure',
+})
+export { e }
diff --git a/examples/with-edgedb/components/Header.tsx b/examples/with-edgedb/components/Header.tsx
new file mode 100644
index 000000000000..84ac53b51696
--- /dev/null
+++ b/examples/with-edgedb/components/Header.tsx
@@ -0,0 +1,55 @@
+import React from 'react'
+import Link from 'next/link'
+
+const Header: React.FC = () => {
+ return (
+
+ )
+}
+
+export default Header
diff --git a/examples/with-edgedb/components/Layout.tsx b/examples/with-edgedb/components/Layout.tsx
new file mode 100644
index 000000000000..2ccd1e683196
--- /dev/null
+++ b/examples/with-edgedb/components/Layout.tsx
@@ -0,0 +1,51 @@
+import React, { ReactNode } from 'react'
+import Header from './Header'
+
+type Props = {
+ children: ReactNode
+}
+
+const Layout: React.FC = (props) => (
+
+
+
{props.children}
+
+
+
+)
+
+export default Layout
diff --git a/examples/with-edgedb/components/Post.tsx b/examples/with-edgedb/components/Post.tsx
new file mode 100644
index 000000000000..9a7b6a7e8b9e
--- /dev/null
+++ b/examples/with-edgedb/components/Post.tsx
@@ -0,0 +1,40 @@
+import React from 'react'
+import ReactMarkdown from 'react-markdown'
+import Link from 'next/link'
+import { PostProps } from '../pages/blog/[id]'
+
+const Post: React.FC<{ post: PostProps }> = ({ post }) => {
+ return (
+
+