diff --git a/.changeset/brown-apricots-refuse.md b/.changeset/brown-apricots-refuse.md
new file mode 100644
index 0000000000..231fed66d9
--- /dev/null
+++ b/.changeset/brown-apricots-refuse.md
@@ -0,0 +1,7 @@
+---
+"nextra": patch
+"nextra-theme-blog": patch
+"nextra-theme-docs": patch
+---
+
+pass unstable_flexsearch
diff --git a/.changeset/nasty-radios-joke.md b/.changeset/nasty-radios-joke.md
index 2a50fc51b1..f5ac670e91 100644
--- a/.changeset/nasty-radios-joke.md
+++ b/.changeset/nasty-radios-joke.md
@@ -1,5 +1,5 @@
---
-'nextra-theme-docs': patch
+"nextra-theme-docs": patch
---
chore(nextra-theme-docs): refactor `theme-context.ts`
diff --git a/.changeset/olive-lions-help.md b/.changeset/olive-lions-help.md
index 24f8887be6..e358595144 100644
--- a/.changeset/olive-lions-help.md
+++ b/.changeset/olive-lions-help.md
@@ -1,7 +1,7 @@
---
-'nextra': patch
-'nextra-theme-blog': patch
-'nextra-theme-docs': patch
+"nextra": patch
+"nextra-theme-blog": patch
+"nextra-theme-docs": patch
---
Fix release workflow.
diff --git a/.changeset/pretty-tips-invite.md b/.changeset/pretty-tips-invite.md
index 151a354e40..fa9a41a5ba 100644
--- a/.changeset/pretty-tips-invite.md
+++ b/.changeset/pretty-tips-invite.md
@@ -1,5 +1,5 @@
---
-'nextra': patch
+"nextra": patch
---
feat(nextra): allow define custom languages for shiki with `mdxOptions.rehypePrettyCodeOptions` option
diff --git a/.changeset/rude-colts-agree.md b/.changeset/rude-colts-agree.md
index 63728779fb..cdc94b9085 100644
--- a/.changeset/rude-colts-agree.md
+++ b/.changeset/rude-colts-agree.md
@@ -1,5 +1,5 @@
---
-'nextra-theme-blog': patch
+"nextra-theme-blog": patch
---
fix(nextra-theme-blog): make nav items center aligned
diff --git a/.changeset/thin-peaches-drive.md b/.changeset/thin-peaches-drive.md
index 3692ddb6f6..11b6965dbf 100644
--- a/.changeset/thin-peaches-drive.md
+++ b/.changeset/thin-peaches-drive.md
@@ -1,5 +1,5 @@
---
-'nextra-theme-docs': patch
+"nextra-theme-docs": patch
---
feat(nextra-theme-docs): update discord logo to the new one
diff --git a/.changeset/two-dots-play.md b/.changeset/two-dots-play.md
index 9ca118a32b..222a7088e1 100644
--- a/.changeset/two-dots-play.md
+++ b/.changeset/two-dots-play.md
@@ -1,5 +1,5 @@
---
-'nextra': patch
+"nextra": patch
---
fix(nextra): allow to contain dots in page filenames
diff --git a/.prettierignore b/.prettierignore
new file mode 100644
index 0000000000..514e5eab56
--- /dev/null
+++ b/.prettierignore
@@ -0,0 +1,5 @@
+dist
+.next
+pnpm-lock.yaml
+pnpm-workspace.yaml
+.changeset
\ No newline at end of file
diff --git a/examples/blog/pages/posts/aaron-swartz-a-programmable-web.mdx b/examples/blog/pages/posts/aaron-swartz-a-programmable-web.mdx
index f941d00f96..77cb15b9b6 100644
--- a/examples/blog/pages/posts/aaron-swartz-a-programmable-web.mdx
+++ b/examples/blog/pages/posts/aaron-swartz-a-programmable-web.mdx
@@ -1,32 +1,31 @@
---
title: Notes on A Programmable Web by Aaron Swartz
date: 2016/5/21
-description: At the time when I was getting into web development, I had the chance to read one of the most inspiring book about the web, Aaron Swartz's A Programmable Web. And it completely changed my mind.
+description: At the time when I was getting into web development, I had the chance to read one of the most inspiring book about the web, Aaron Swartz's A Programmable Web. And it completely changed my mind.
tag: web development
author: Shu
---
# Notes on A Programmable Web by Aaron Swartz
-At the time when I was getting into web development, I had the chance to read one of the most inspiring book about the web, Aaron Swartz's A Programmable Web. And it completely changed my mind.
+At the time when I was getting into web development, I had the chance to read one of the most inspiring book about the web, Aaron Swartz's A Programmable Web. And it completely changed my mind.
**Updated in 2017**: [@tommyjtl](https://github.com/tommyjtl), [@zimine](https://github.com/zimine) and I are currently helping translate this post into Simplified Chinese. Any [contributions](https://github.com/tommyjtl/the-programmable-web/tree/translation) are welcomed :)
---
-> Sure, it sounds a little bit crazy. But it paid off the last time they made that gamble: we ended up with a little thing called the World Wide Web.
-Let's see if they can do it again.
+> Sure, it sounds a little bit crazy. But it paid off the last time they made that gamble: we ended up with a little thing called the World Wide Web.
+> Let's see if they can do it again.
— Aaron
Read Aaron's original post: [Building Programmable Web Sites by Aaron Swartz, 2009](http://www.cs.rpi.edu/~hendler/ProgrammableWebSwartz2009.html).
-
## Quotes About WWW
1. “(the Internet) It should be kept open. It should be kept free.” – Steve Jobs
2. “The third reason it’s very exciting is that Microsoft doesn’t own it and I don’t think they can. It’s the one thing in the industry that Microsoft can probably never own. I think one of the things that’s essential is that the government continue to fund the Internet as a public trust, as a public facility and remove any of these ridiculous notions of privatizing it that have been brought up. I don’t think they’re going to fly, thankfully.” – Steve Jobs
-3. Jacques Mattheij wrote an article, about the web in 2050, which feels like the *New Speak* in George Orwell's *1984*.
+3. Jacques Mattheij wrote an article, about the web in 2050, which feels like the *New Speak* in George Orwell's _1984_.
## Quotes from Aaron’s Post
@@ -76,4 +75,4 @@ Instead, they used the clone created by a team at the University of Illinois Urb
4. [“URLs shouldn't include technical details”: 天猫首页](https://www.zhihu.com/question/54777923/answer/141058259)
5. [Semantic Web – W3C](https://www.w3.org/standards/semanticweb)
6. [Tim Berners-Lee: The next web](https://www.ted.com/talks/tim_berners_lee_on_the_next_web)
-7. [The Web in 2050 · Jacques Mattheij](https://jacquesmattheij.com/the-web-in-2050): “reboot the web”
\ No newline at end of file
+7. [The Web in 2050 · Jacques Mattheij](https://jacquesmattheij.com/the-web-in-2050): “reboot the web”
diff --git a/examples/docs/next.config.js b/examples/docs/next.config.js
index b3ccf55e61..635ef549ec 100644
--- a/examples/docs/next.config.js
+++ b/examples/docs/next.config.js
@@ -1,7 +1,10 @@
const withNextra = require('nextra')({
theme: 'nextra-theme-docs',
themeConfig: './src/theme.config.js',
- unstable_staticImage: true
+ unstable_staticImage: true,
+ unstable_flexsearch: {
+ codeblock: false
+ }
})
module.exports = withNextra({
diff --git a/examples/docs/public/android-icon-192x192.png b/examples/docs/public/android-icon-192x192.png
new file mode 100644
index 0000000000..538ee26b84
Binary files /dev/null and b/examples/docs/public/android-icon-192x192.png differ
diff --git a/examples/docs/public/apple-icon-180x180.png b/examples/docs/public/apple-icon-180x180.png
new file mode 100644
index 0000000000..e776c41058
Binary files /dev/null and b/examples/docs/public/apple-icon-180x180.png differ
diff --git a/examples/docs/public/apple-icon.png b/examples/docs/public/apple-icon.png
new file mode 100644
index 0000000000..a3b5b9cecd
Binary files /dev/null and b/examples/docs/public/apple-icon.png differ
diff --git a/examples/docs/public/demo.png b/examples/docs/public/demo.png
new file mode 100644
index 0000000000..3751514339
Binary files /dev/null and b/examples/docs/public/demo.png differ
diff --git a/examples/docs/public/favicon-16x16.png b/examples/docs/public/favicon-16x16.png
new file mode 100644
index 0000000000..a926d89480
Binary files /dev/null and b/examples/docs/public/favicon-16x16.png differ
diff --git a/examples/docs/public/favicon-32x32.png b/examples/docs/public/favicon-32x32.png
new file mode 100644
index 0000000000..35d3f5c106
Binary files /dev/null and b/examples/docs/public/favicon-32x32.png differ
diff --git a/examples/docs/public/favicon-96x96.png b/examples/docs/public/favicon-96x96.png
new file mode 100644
index 0000000000..d18801609f
Binary files /dev/null and b/examples/docs/public/favicon-96x96.png differ
diff --git a/examples/docs/public/favicon.ico b/examples/docs/public/favicon.ico
new file mode 100644
index 0000000000..3f2bd59287
Binary files /dev/null and b/examples/docs/public/favicon.ico differ
diff --git a/examples/docs/public/img.jpeg b/examples/docs/public/img.jpeg
deleted file mode 100644
index 2aa4ada519..0000000000
Binary files a/examples/docs/public/img.jpeg and /dev/null differ
diff --git a/examples/docs/public/ms-icon-144x144.png b/examples/docs/public/ms-icon-144x144.png
new file mode 100644
index 0000000000..0c7268e1ef
Binary files /dev/null and b/examples/docs/public/ms-icon-144x144.png differ
diff --git a/examples/docs/public/og.png b/examples/docs/public/og.png
new file mode 100644
index 0000000000..3ec73a67d7
Binary files /dev/null and b/examples/docs/public/og.png differ
diff --git a/examples/docs/public/stork.wasm b/examples/docs/public/stork.wasm
deleted file mode 100644
index 9cb0f659b6..0000000000
Binary files a/examples/docs/public/stork.wasm and /dev/null differ
diff --git a/examples/docs/src/pages/_app.js b/examples/docs/src/pages/_app.js
index 9f63bdaedf..6639972e0c 100644
--- a/examples/docs/src/pages/_app.js
+++ b/examples/docs/src/pages/_app.js
@@ -1,8 +1,6 @@
import 'nextra-theme-docs/style.css'
-export default function MyApp({ Component, pageProps }) {
- // Use the layout defined at the page level, if available
+export default function Nextra({ Component, pageProps }) {
const getLayout = Component.getLayout || (page => page)
-
return getLayout()
}
diff --git a/examples/docs/src/pages/advanced/code-highlighting.mdx b/examples/docs/src/pages/advanced/code-highlighting.mdx
new file mode 100644
index 0000000000..ea23a202c8
--- /dev/null
+++ b/examples/docs/src/pages/advanced/code-highlighting.mdx
@@ -0,0 +1,54 @@
+# Code Highlighting
+
+`Nextra` uses [Shiki](https://shiki.matsu.io) and [Rehype Pretty Code](https://github.com/FormidableLabs/prism-react-renderer)
+to highlight the code blocks. This section covers how you can customze it.
+
+## Meta strings
+
+### Highlight lines
+
+````mdx
+```jsx {1,3-5}
+import 'nextra-theme-docs/style.css'
+
+export default function Nextra({ Component, pageProps }) {
+ const getLayout = Component.getLayout || (page => page)
+ return getLayout()
+}
+```
+````
+
+```jsx {1,4-5}
+import 'nextra-theme-docs/style.css'
+
+export default function Nextra({ Component, pageProps }) {
+ const getLayout = Component.getLayout || (page => page)
+ return getLayout()
+}
+```
+
+### Title
+
+````mdx
+```jsx filename="_app.js"
+import 'nextra-theme-docs/style.css'
+
+export default function Nextra({ Component, pageProps }) {
+ const getLayout = Component.getLayout || (page => page)
+ return getLayout()
+}
+```
+````
+
+```jsx filename="_app.js"
+import 'nextra-theme-docs/style.css'
+
+export default function Nextra({ Component, pageProps }) {
+ const getLayout = Component.getLayout || (page => page)
+ return getLayout()
+}
+```
+
+## Supported Languages
+
+You can find a list of supported languages [here](https://github.com/shikijs/shiki/blob/main/docs/languages.md).
diff --git a/examples/docs/src/pages/advanced/meta.json b/examples/docs/src/pages/advanced/meta.json
new file mode 100644
index 0000000000..92b138d580
--- /dev/null
+++ b/examples/docs/src/pages/advanced/meta.json
@@ -0,0 +1,3 @@
+{
+ "code-highlighting": "Code Highlighting"
+}
diff --git a/examples/docs/src/pages/blog/hello-world.md b/examples/docs/src/pages/blog/hello-world.md
deleted file mode 100644
index 1158454045..0000000000
--- a/examples/docs/src/pages/blog/hello-world.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# My first post!
-
-hello, world!
diff --git a/examples/docs/src/pages/blog/meta.json b/examples/docs/src/pages/blog/meta.json
deleted file mode 100644
index 893ecb1492..0000000000
--- a/examples/docs/src/pages/blog/meta.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "hello-world": "Hello, World!"
-}
\ No newline at end of file
diff --git a/examples/docs/src/pages/features/i18n.mdx b/examples/docs/src/pages/features/i18n.mdx
new file mode 100644
index 0000000000..2e257cf74d
--- /dev/null
+++ b/examples/docs/src/pages/features/i18n.mdx
@@ -0,0 +1,43 @@
+import Callout from 'nextra-theme-docs/callout'
+
+# Next.js I18n
+
+This feature is only available in the docs theme.
+
+Nextra supports [Next.js Internationalized Routing](https://nextjs.org/docs/advanced-features/i18n-routing) out of the box.
+
+To add multi-language pages to your Nextra application, just need to config `i18n` in `next.config.js`:
+
+```js filename="next.config.js"
+const withNextra = require('nextra')('nextra-theme-docs', './theme.config.js')
+module.exports = withNextra({
+ i18n: {
+ locales: ['en', 'zh', 'de'],
+ defaultLocale: 'en'
+ }
+})
+```
+
+Then, add the locale codes to your file extensions (required for the default locale too):
+
+```plaintext
+/pages
+ index.en.md
+ index.zh.md
+ index.de.md
+ meta.en.json
+ meta.zh.json
+ meta.de.json
+ ...
+```
+
+Finally, add the `i18n` option to your `theme.config.js` to configure the language dropdown:
+
+```jsx filename="theme.config.js"
+i18n: [
+ { locale: 'en', text: 'English' },
+ { locale: 'zh', text: '中文' },
+ { locale: 'de', text: 'Deutsch' },
+ { locale: 'ar', text: 'العربية', direction: 'rtl' }
+]
+```
diff --git a/examples/docs/src/pages/features/image.mdx b/examples/docs/src/pages/features/image.mdx
new file mode 100644
index 0000000000..3163883790
--- /dev/null
+++ b/examples/docs/src/pages/features/image.mdx
@@ -0,0 +1,33 @@
+# Next.js Image
+
+You can use [Next.js Image](https://nextjs.org/docs/basic-features/image-optimization) directly in MDX.
+
+If the `demo.png` file is located at `/public/demo.png`, you can use the code below to display it:
+
+```mdx
+import Image from 'next/image'
+
+
+```
+
+## Static Image
+
+import Callout from 'nextra-theme-docs/callout'
+
+
+ You need to opt-in to this feature by enabling [`unstable_staticImage:
+ true`](/get-started#create-manually).
+
+
+Nextra also supports automatic static image imports, you no longer need to specify the width and height of the image manually,
+and you can directly use the Markdown syntax to display the same image:
+
+```markdown
+![Hello](../../../public/demo.png)
+```
+
+With Next.js Image, there will be no layout shift, and a beautiful blury placeholder will be shown by default when loading the images:
+
+
+
+![Nextra](../../../public/og.png)
diff --git a/examples/docs/src/pages/features/mdx.mdx b/examples/docs/src/pages/features/mdx.mdx
new file mode 100644
index 0000000000..e3eb15a03a
--- /dev/null
+++ b/examples/docs/src/pages/features/mdx.mdx
@@ -0,0 +1,161 @@
+# MDX
+
+With Nextra, all your `.md` and `.mdx` files under the pages directory will be rendered with [MDX](https://mdxjs.com/about), it's an
+advanced Markdown format with React component support.
+
+You can use import and use React components inside your Markdown files like this:
+
+```mdx filename="example.mdx"
+import Callout from 'nextra-theme-docs/callout'
+
+**Markdown With React Components**
+
+
+ **MDX** (the library), at its core, transforms MDX (the syntax) to JSX. It
+ receives an MDX string and outputs a _JSX string_. It does this by parsing the
+ MDX document to a syntax tree and then generates a JSX document from that
+ tree.
+
+```
+
+Generates:
+
+import Callout from 'nextra-theme-docs/callout'
+
+
+**Markdown With React Components**
+
+
+ **MDX** (the library), at its core, transforms MDX (the syntax) to JSX. It
+ receives an MDX string and outputs a _JSX string_. It does this by parsing the
+ MDX document to a syntax tree and then generates a JSX document from that
+ tree.
+
+
+
+## Heading
+
+
+
+# **Hello**, This Is a _Title_ Inside `h1`
+
+
**Hello**, This Is a _Title_ Inside `h2`
+{/* using html tag to avoid being rendered in the sidebar */}
+
+### **Hello**, This Is a _Title_ Inside `h3`
+
+#### **Hello**, This Is a _Title_ Inside `h4`
+
+##### **Hello**, This Is a _Title_ Inside `h5`
+
+###### **Hello**, This Is a _Title_ Inside `h6`
+
+## List
+
+1. one
+2. two
+3. three
+
+- one
+- two
+- three
+
+## Task List
+
+```mdx
+- [x] Write the press release
+- [ ] Update the website
+- [ ] Contact the media
+```
+
+Renders
+
+- [x] Write the press release
+- [ ] Update the website
+- [ ] Contact the media
+
+## Syntax Highlighting
+
+Automatic syntax highlighting
+
+````mdx
+```js
+console.log('hello, world')
+```
+````
+
+Renders:
+
+```js
+console.log('hello, world')
+```
+
+You can also add the `{line|range}` modifier to highlight specific lines:
+
+````mdx
+```jsx {4,6-8}
+import useSWR from 'swr'
+
+function Profile() {
+ const { data, error } = useSWR('/api/user', fetcher)
+
+ if (error) return
+}
+```
+
+## Inline Code
+
+You can use \`content\` to wrap inline code content like: `let x = 1`.
+
+## Blockquote
+
+> Where some people measure progress in answers-right per test or tests-passed per year, we are more interested in Sistine-Chapel-Ceilings per Lifetime.
+>
+> — Alan Kay, A Personal Computer for Children of All Ages
+
+Nested quotes:
+
+> > Where some people measure progress in answers-right per test or tests-passed per year, we are more interested in Sistine-Chapel-Ceilings per Lifetime.
+> >
+> > — Alan Kay, A Personal Computer for Children of All Ages
+>
+> This is **great**.
+>
+> — Shu Ding.
+
+## Table
+
+| Syntax | Description | Test Text |
+| :------------ | :---------: | ----------: |
+| Header | Title | Here's this |
+| Paragraph | Text | And more |
+| Strikethrough | | ~~Text~~ |
+
+## React Components
+
+React components and Markdown can be **mixed together**, for instance:
+
+```mdx
+Give [**Nextra**](https://github.com/shuding/nextra) a star!
+```
+
+Renders:
+
+>
+> Give [**Nextra**](https://github.com/shuding/nextra) a star!
+>
diff --git a/examples/docs/src/pages/features/meta.json b/examples/docs/src/pages/features/meta.json
new file mode 100644
index 0000000000..369452f003
--- /dev/null
+++ b/examples/docs/src/pages/features/meta.json
@@ -0,0 +1,7 @@
+{
+ "mdx": "MDX",
+ "ssg": "Next.js SSG",
+ "i18n": "Next.js i18n",
+ "image": "Next.js Image",
+ "themes": "Themes"
+}
diff --git a/examples/docs/src/pages/features/ssg.mdx b/examples/docs/src/pages/features/ssg.mdx
new file mode 100644
index 0000000000..17f729e2a2
--- /dev/null
+++ b/examples/docs/src/pages/features/ssg.mdx
@@ -0,0 +1,68 @@
+# Next.js SSG
+
+With Next.js, you can pre-render your page using [Static Generation (SSG)](https://nextjs.org/docs/basic-features/pages#static-generation-recommended). Your pages will be generated at build time and statically served to visitors. It can also be cached by a CDN to maximize the performance.
+
+This is supported by Nextra too. Here's an example:
+
+import { useSSG } from 'nextra/ssg'
+
+export const getStaticProps = ({ params }) => {
+ return fetch(`https://api.github.com/repos/shuding/nextra`)
+ .then(res => res.json())
+ .then(repo => ({
+ props: {
+ // We add an `ssg` field to the page props,
+ // which will be provided to the Nextra `useSSG` hook.
+ ssg: {
+ stars: repo.stargazers_count || 0
+ }
+ },
+ // The page will be considered as stale and regenerated every 60 seconds.
+ revalidate: 60
+ }))
+}
+
+export const Stars = () => {
+ // Get the data from SSG, and render it as a component.
+ const { stars } = useSSG()
+ return {stars}
+}
+
+