From d676456d8ba936b9840e2e499109ae72207f97f6 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 01:33:12 +0300 Subject: [PATCH 01/40] aa --- docs/app/docs/docs-theme/start/page.mdx | 94 ++++++++++++++++++++----- docs/components/ready-to-go.mdx | 4 +- 2 files changed, 80 insertions(+), 18 deletions(-) diff --git a/docs/app/docs/docs-theme/start/page.mdx b/docs/app/docs/docs-theme/start/page.mdx index 080cf7bfcf..53e608ff4c 100644 --- a/docs/app/docs/docs-theme/start/page.mdx +++ b/docs/app/docs/docs-theme/start/page.mdx @@ -61,37 +61,99 @@ Create the following `next.config.mjs` file in your project's root directory: import nextra from 'nextra' const withNextra = nextra({ - theme: 'nextra-theme-docs', - themeConfig: './theme.config.jsx' + // Other Nextra config options }) -export default withNextra() - // If you have other Next.js configurations, you can pass them as the parameter: -// export default withNextra({ /* other next.js config */ }) +export default withNextra({ + // Other Next.js config options +}) ``` With the above configuration, Nextra can handle Markdown files in your Next.js project, with the specified theme. Other Nextra configurations can be found in [Guide](/docs/guide). -### Create Docs Theme Config +### Add `mdx-components.js` in root directory -Lastly, create the corresponding `theme.config.jsx` file in your project's root -directory. This will be used to configure the Nextra Docs theme: +```ts filename="mdx-components.js" +import { useMDXComponents as getDocsMDXComponents } from 'nextra-theme-docs' -```jsx filename="theme.config.jsx" -export default { - logo: My Nextra Documentation, - project: { - link: 'https://github.com/shuding/nextra' +const docsComponents = getDocsMDXComponents() + +export function useMDXComponents(components) { + return { + ...docsComponents, + ...components } - // ... other theme options } ``` -Full theme configurations can be found -[here](/docs/docs-theme/theme-configuration). +> [!TIP] +> +> You can use `.jsx`, `.ts` and `.tsx` extensions for your `mdx-components` file +> as well. + +### Create Root Layout + +Lastly, create the root layout of your application in `app` folder. This will be +used to configure the Nextra docs theme: + +```jsx filename="app/layout.jsx" +import { Footer, Layout, Navbar } from 'nextra-theme-docs' +import { Banner, Head } from 'nextra/components' +import { getPageMap } from 'nextra/page-map' +import 'nextra-theme-docs/style.css' + +export const metadata = { + // ... Your metadata API + // https://nextjs.org/docs/app/building-your-application/optimizing/metadata +} + +const banner = Nextra 4.0 is released 🎉 +const navbar = ( + Nextra} + // ... Your additional navbar options + /> +) +const footer = ( +
+ MIT {new Date().getFullYear()} © Nextra. +
+) + +export default async function RootLayout({ children }) { + return ( + + + {/* Your additional tags should be passed as `children` of `` element */} + + + + {children} + + + + ) +} +``` diff --git a/docs/components/ready-to-go.mdx b/docs/components/ready-to-go.mdx index a0140fde2d..9cb6e5c5ec 100644 --- a/docs/components/ready-to-go.mdx +++ b/docs/components/ready-to-go.mdx @@ -1,8 +1,8 @@ ### Ready to Go! -Now, you can create your first MDX page as `pages/index.mdx`: +Now, you can create your first MDX page as `content/index.mdx`: -```mdx filename="pages/index.mdx" +```mdx filename="content/index.mdx" # Welcome to Nextra Hello, world! From 2888b805d9fc805029b0fdcb3e7493f77f2faabe Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 01:38:18 +0300 Subject: [PATCH 02/40] more --- docs/app/docs/docs-theme/start/page.mdx | 16 ++++++---------- docs/components/install-nextra-theme.mdx | 6 ++++-- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/docs/app/docs/docs-theme/start/page.mdx b/docs/app/docs/docs-theme/start/page.mdx index 53e608ff4c..ca1f58f06a 100644 --- a/docs/app/docs/docs-theme/start/page.mdx +++ b/docs/app/docs/docs-theme/start/page.mdx @@ -8,11 +8,11 @@ import { Steps } from 'nextra/components' # Docs Theme -Nextra Docs Theme is a theme that includes almost everything you need to build a +Nextra docs theme is a theme that includes almost everything you need to build a modern documentation website. It includes a top navigation bar, a search bar, a pages sidebar, a Table of Contents (TOC), and other built-in components. -This website itself is built with the Nextra Docs Theme. +This website itself is built with the Nextra docs theme. ## Quick Start from Template @@ -24,7 +24,7 @@ clicking the link: [![](https://vercel.com/button)](https://vercel.com/new/clone?s=https%3A%2F%2Fgithub.com%2Fshuding%2Fnextra-docs-template&showOptionalTeamCreation=false) Vercel will fork the -[Nextra Docs template](https://github.com/shuding/nextra-docs-template) and +[Nextra docs template](https://github.com/shuding/nextra-docs-template) and deploy the site for you. Once done, every commit in the repository will be deployed automatically. @@ -38,8 +38,8 @@ You can also manually fork the ### Install -To create a Nextra Docs site manually, you have to install **Next.js**, -**React**, **Nextra**, and **Nextra Docs Theme**. In your project directory, run +To create a Nextra docs site manually, you have to install **Next.js**, +**React**, **Nextra**, and **Nextra docs theme**. In your project directory, run the following command to install the dependencies: ```sh npm2yarn @@ -117,11 +117,7 @@ const navbar = ( // ... Your additional navbar options /> ) -const footer = ( -
- MIT {new Date().getFullYear()} © Nextra. -
-) +const footer =
MIT {new Date().getFullYear()} © Nextra.
export default async function RootLayout({ children }) { return ( diff --git a/docs/components/install-nextra-theme.mdx b/docs/components/install-nextra-theme.mdx index e1ef0bc668..989450cfd3 100644 --- a/docs/components/install-nextra-theme.mdx +++ b/docs/components/install-nextra-theme.mdx @@ -1,5 +1,3 @@ -import { Callout } from 'nextra/components' - Add the following scripts in `package.json`: ```json filename="package.json" @@ -10,6 +8,10 @@ Add the following scripts in `package.json`: }, ``` +> [!TIP] +> +> You can use Turbopack by appending `--turbopack` flag in `dev` command + You can start the server in development mode with the following command according to your package manager: From 08a8328a5c689f4ae870caa950d604aa3f6a35e0 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 01:43:37 +0300 Subject: [PATCH 03/40] more --- docs/app/docs/guide/organize-files/page.mdx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/app/docs/guide/organize-files/page.mdx b/docs/app/docs/guide/organize-files/page.mdx index a0400cbbda..2646697b39 100644 --- a/docs/app/docs/guide/organize-files/page.mdx +++ b/docs/app/docs/guide/organize-files/page.mdx @@ -4,7 +4,7 @@ import { Cards, FileTree } from 'nextra/components' # Organize Files Nextra first collects all your Markdown files and configurations from the -`pages` directory, and then generates the "page map information" of your entire +`content` directory, and then generates the "page map information" of your entire site, to render things such as the _navigation bar_ and _sidebar_ below:
@@ -27,7 +27,7 @@ from filenames. For example if you have the following structure: - + @@ -104,7 +104,7 @@ for JavaScript objects. Following: -```js filename="pages/_meta.js" +```js filename="content/_meta.js" export default { foo: '', 1992_10_21: '', @@ -115,7 +115,7 @@ export default { Will be converted to: {/* prettier-ignore */} -```js filename="pages/_meta.js" +```js filename="content/_meta.js" export default { '1': '', '19921021': '', @@ -125,9 +125,9 @@ export default { ## Example -Put this in your `pages/_meta.js` file: +Put this in your `content/_meta.js` file: -```js filename="pages/_meta.js" +```js filename="content/_meta.js" export default { index: 'My Homepage', contact: 'Contact Us', From ebda5c1aa75bb7083a069aafcdc1c6821e1bcc7f Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 01:55:09 +0300 Subject: [PATCH 04/40] more --- docs/app/docs/advanced/tailwind-css/page.mdx | 24 ++++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/app/docs/advanced/tailwind-css/page.mdx b/docs/app/docs/advanced/tailwind-css/page.mdx index 1ee175ebc5..63a01e9f1d 100644 --- a/docs/app/docs/advanced/tailwind-css/page.mdx +++ b/docs/app/docs/advanced/tailwind-css/page.mdx @@ -10,10 +10,10 @@ and `.mdx` files to the `content` list in `tailwind.config.js`: ```js filename="tailwind.config.js" /md,mdx/ /** @type {import('tailwindcss').Config} */ -module.exports = { +export default { content: [ - './pages/**/*.{js,jsx,ts,tsx,md,mdx}', - './components/**/*.{js,jsx,ts,tsx,md,mdx}', + './app/**/*.{js,jsx,ts,tsx,md,mdx}', + './content/**/*.{md,mdx}', // Or if using `src` directory: './src/**/*.{js,jsx,ts,tsx,md,mdx}' @@ -25,6 +25,10 @@ module.exports = { } ``` +> [!TIP] +> +> You can use `tailwind.config.ts` as well. + Next step, create a CSS file for Tailwind directives, `globals.css` for example: ```css filename="globals.css" @@ -33,12 +37,18 @@ Next step, create a CSS file for Tailwind directives, `globals.css` for example: @tailwind utilities; ``` -Then import into `pages/_app.jsx` +> [!TIP] +> +> You don't need to have `@tailwind base` directive while using `nextra-theme-docs` or +> `nextra-theme-blog` because they already imports Tailwind CSS preflight styles in +> their `style.css` files + +Then import in root layout file -```jsx filename="_app.jsx" +```jsx filename="app/layout.jsx" import '../path/to/your/globals.css' -export default function App({ Component, pageProps }) { - return +export default async function RootLayout({ children }) { + // ... } ``` From 32ba635e484c549f653832ac2c14b1852adf1a45 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 02:00:26 +0300 Subject: [PATCH 05/40] more --- docs/app/docs/advanced/tailwind-css/page.mdx | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/app/docs/advanced/tailwind-css/page.mdx b/docs/app/docs/advanced/tailwind-css/page.mdx index 63a01e9f1d..d330e734dc 100644 --- a/docs/app/docs/advanced/tailwind-css/page.mdx +++ b/docs/app/docs/advanced/tailwind-css/page.mdx @@ -1,3 +1,5 @@ +import { Steps } from 'nextra/components' + # Tailwind CSS Tailwind CSS is a CSS framework that provides a set of pre-defined CSS classes @@ -5,6 +7,10 @@ to quickly style elements. You can follow the official [Tailwind CSS documentation for Next.js](https://tailwindcss.com/docs/guides/nextjs) to set up Tailwind CSS for your Nextra project. + + +## Create `tailwind.config.js` file + To use Tailwind classes in your Markdown files, you will also need to add `.md` and `.mdx` files to the `content` list in `tailwind.config.js`: @@ -29,21 +35,23 @@ export default { > > You can use `tailwind.config.ts` as well. -Next step, create a CSS file for Tailwind directives, `globals.css` for example: +## Create `globals.css` file + +Create a CSS file for Tailwind directives, `globals.css` for example: ```css filename="globals.css" -@tailwind base; +@tailwind base; /* preflight styles */ @tailwind components; @tailwind utilities; ``` -> [!TIP] +> [!NOTE] > > You don't need to have `@tailwind base` directive while using `nextra-theme-docs` or > `nextra-theme-blog` because they already imports Tailwind CSS preflight styles in -> their `style.css` files +> their `style.css` files. -Then import in root layout file +## Import styles in root layout ```jsx filename="app/layout.jsx" import '../path/to/your/globals.css' @@ -52,3 +60,5 @@ export default async function RootLayout({ children }) { // ... } ``` + + From 4d51b6fb100a8dd56a5dd8c7a37eba0c2074dfe7 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 02:01:45 +0300 Subject: [PATCH 06/40] more --- docs/app/docs/built-ins/filetree/page.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/app/docs/built-ins/filetree/page.mdx b/docs/app/docs/built-ins/filetree/page.mdx index 3a073396a7..c18f7d829e 100644 --- a/docs/app/docs/built-ins/filetree/page.mdx +++ b/docs/app/docs/built-ins/filetree/page.mdx @@ -14,7 +14,7 @@ A built-in component to visually represent a file tree. Click the folder to test the dynamic functionality of the file tree. - + @@ -36,7 +36,7 @@ with the `name` attribute. Use `defaultOpen` to set the folder to open on load. import { FileTree } from 'nextra/components' - + From cb75b880e18976a52eae901358f661aaecbb6817 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 02:05:58 +0300 Subject: [PATCH 07/40] more --- docs/app/docs/custom-theme/page.mdx | 8 +++----- docs/app/docs/docs-theme/built-ins/layout/page.mdx | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/docs/app/docs/custom-theme/page.mdx b/docs/app/docs/custom-theme/page.mdx index 31df82365f..17d724e7e6 100644 --- a/docs/app/docs/custom-theme/page.mdx +++ b/docs/app/docs/custom-theme/page.mdx @@ -37,10 +37,8 @@ const withNextra = nextra({ You can now start working on your theme! In your root directory, create the corresponding `theme.tsx` file with basic content: -```tsx filename="theme.tsx" /children/ -import type { NextraThemeLayoutProps } from 'nextra' - -export default function Layout({ children }: NextraThemeLayoutProps) { +```tsx filename="theme.jsx" /children/ +export default function Layout({ children }) { return (

My Theme

@@ -52,7 +50,7 @@ export default function Layout({ children }: NextraThemeLayoutProps) { It accepts a `children` prop, which is the MDX content of the current page, and wraps some other elements around the content. After creating the theme, you can -simply add a MDX file as `pages/index.mdx` and see the result: +simply add a MDX file as `content/index.mdx` and see the result: ![Custom theme](/assets/docs/custom-theme.png) diff --git a/docs/app/docs/docs-theme/built-ins/layout/page.mdx b/docs/app/docs/docs-theme/built-ins/layout/page.mdx index 3a8eddda02..8821b12029 100644 --- a/docs/app/docs/docs-theme/built-ins/layout/page.mdx +++ b/docs/app/docs/docs-theme/built-ins/layout/page.mdx @@ -244,7 +244,7 @@ export default { In addition, you can customize the sidebar title using the `sidebarTitle` property in your front matter: -```mdx filename="pages/getting-started.mdx" +```mdx filename="getting-started.mdx" --- sidebarTitle: Getting Started 🚀 --- From 07f4159020971c6de7c199fb3808dd21823ce657 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 02:08:50 +0300 Subject: [PATCH 08/40] more --- docs/app/docs/advanced/tailwind-css/page.mdx | 6 +++--- docs/app/docs/blog-theme/start/page.mdx | 9 ++++----- docs/app/docs/custom-theme/page.mdx | 4 +++- docs/app/docs/docs-theme/start/page.mdx | 4 ++-- docs/app/docs/guide/organize-files/page.mdx | 4 ++-- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/docs/app/docs/advanced/tailwind-css/page.mdx b/docs/app/docs/advanced/tailwind-css/page.mdx index d330e734dc..19d4749445 100644 --- a/docs/app/docs/advanced/tailwind-css/page.mdx +++ b/docs/app/docs/advanced/tailwind-css/page.mdx @@ -47,9 +47,9 @@ Create a CSS file for Tailwind directives, `globals.css` for example: > [!NOTE] > -> You don't need to have `@tailwind base` directive while using `nextra-theme-docs` or -> `nextra-theme-blog` because they already imports Tailwind CSS preflight styles in -> their `style.css` files. +> You don't need to have `@tailwind base` directive while using +> `nextra-theme-docs` or `nextra-theme-blog` because they already imports +> Tailwind CSS preflight styles in their `style.css` files. ## Import styles in root layout diff --git a/docs/app/docs/blog-theme/start/page.mdx b/docs/app/docs/blog-theme/start/page.mdx index 7448dcb0e8..08e14c01a0 100644 --- a/docs/app/docs/blog-theme/start/page.mdx +++ b/docs/app/docs/blog-theme/start/page.mdx @@ -40,14 +40,13 @@ Create the following `next.config.mjs` file in your project's root directory: import nextra from 'nextra' const withNextra = nextra({ - theme: 'nextra-theme-blog', - themeConfig: './theme.config.jsx' + // ... Other Nextra config options }) -export default withNextra() - // If you have other Next.js configurations, you can pass them as the parameter: -// export default withNextra({ /* other next.js config */ }) +export default withNextra({ + // ... Other Next.js config options +}) ``` With the above configuration, Nextra can handle Markdown files in your Next.js diff --git a/docs/app/docs/custom-theme/page.mdx b/docs/app/docs/custom-theme/page.mdx index 17d724e7e6..6f855a8318 100644 --- a/docs/app/docs/custom-theme/page.mdx +++ b/docs/app/docs/custom-theme/page.mdx @@ -29,7 +29,9 @@ const withNextra = nextra({ }) // If you have other Next.js configurations, you can pass them as the parameter: -// export default withNextra({ /* other next.js config */ }) +export default withNextra({ + // ... Other Next.js config options +}) ``` ### Create a Basic Theme diff --git a/docs/app/docs/docs-theme/start/page.mdx b/docs/app/docs/docs-theme/start/page.mdx index ca1f58f06a..9432596a59 100644 --- a/docs/app/docs/docs-theme/start/page.mdx +++ b/docs/app/docs/docs-theme/start/page.mdx @@ -61,12 +61,12 @@ Create the following `next.config.mjs` file in your project's root directory: import nextra from 'nextra' const withNextra = nextra({ - // Other Nextra config options + // ... Other Nextra config options }) // If you have other Next.js configurations, you can pass them as the parameter: export default withNextra({ - // Other Next.js config options + // ... Other Next.js config options }) ``` diff --git a/docs/app/docs/guide/organize-files/page.mdx b/docs/app/docs/guide/organize-files/page.mdx index 2646697b39..b526078d94 100644 --- a/docs/app/docs/guide/organize-files/page.mdx +++ b/docs/app/docs/guide/organize-files/page.mdx @@ -4,8 +4,8 @@ import { Cards, FileTree } from 'nextra/components' # Organize Files Nextra first collects all your Markdown files and configurations from the -`content` directory, and then generates the "page map information" of your entire -site, to render things such as the _navigation bar_ and _sidebar_ below: +`content` directory, and then generates the "page map information" of your +entire site, to render things such as the _navigation bar_ and _sidebar_ below:
From fd98602f78478f151a23371bad723bd4584169e2 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 02:24:59 +0300 Subject: [PATCH 09/40] more --- .../docs-theme/page-configuration/page.mdx | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/app/docs/docs-theme/page-configuration/page.mdx b/docs/app/docs/docs-theme/page-configuration/page.mdx index b2f5b44711..0adddd8de1 100644 --- a/docs/app/docs/docs-theme/page-configuration/page.mdx +++ b/docs/app/docs/docs-theme/page-configuration/page.mdx @@ -23,7 +23,7 @@ The title and order of a page shown in the sidebar should be configured in the structure: - + @@ -52,7 +52,7 @@ export default { Folders can be configured in the same way as pages. For example: - + @@ -68,7 +68,7 @@ Folders can be configured in the same way as pages. For example: The top-level `_meta.js` file contains the meta information for the top-level pages and folders: -```js filename="pages/_meta.js" +```js filename="content/_meta.js" export default { index: 'My Homepage', contact: 'Contact Us', @@ -80,7 +80,7 @@ export default { And the nested `_meta.js` file contains the meta information for pages in the same folder: -```js filename="pages/fruits/_meta.js" +```js filename="content/fruits/_meta.js" export default { apple: 'Apple', banana: 'Banana' @@ -95,10 +95,10 @@ move directories around without having to change the `_meta.js` file. What if I want to have a folder with an index page? We can add a MDX page with the same name and in the same directory as the folder. Let's say we want to add `/fruits` route in the example above, we can create a `fruits.mdx` file in -pages: +`content`: - + @@ -121,7 +121,7 @@ show you the `fruits.mdx` page at the same time. You can add external links to the sidebar by adding an item with `href` in `_meta.js`: -```js filename="pages/_meta.js" {6-9} +```js filename="content/_meta.js" {6-9} export default { index: 'My Homepage', contact: 'Contact Us', @@ -144,7 +144,7 @@ By default, all MDX routes in the filesystem will be shown on the sidebar. But you can hide a specific pages or folders by using the `"display": "hidden"` configuration: -```js filename="pages/_meta.js" {4} +```js filename="content/_meta.js" {4} export default { index: 'My Homepage', contact: { @@ -170,7 +170,7 @@ For example, you can have 2 docs folders `frameworks` and `fruits` in your project: - + @@ -189,7 +189,7 @@ project: In your top-level `_meta.js` file, you can set everything as a page, instead of a normal sidebar item: -```js filename="pages/_meta.js" +```js filename="content/_meta.js" export default { index: { title: 'Home', @@ -234,7 +234,7 @@ option: StackBlitz](https://stackblitz.com/edit/nextra-2-docs-2qopvp?file=pages%2F_meta.js)
-```js filename="pages/_meta.js" +```js filename="content/_meta.js" export default { company: { title: 'Company', @@ -258,7 +258,7 @@ export default { Same as the [External Links](#external-links) option, you can have external links in the navbar too: -```js filename="pages/_meta.js" +```js filename="content/_meta.js" export default { index: { title: 'Home', @@ -282,7 +282,7 @@ In the [Sub Docs](#sub-docs) example above, we have to define the `"type": "page"` option for every page. To make it easier, you can use the `"*"` key to define the fallback configuration for all items in this folder: -```js filename="pages/_meta.js" {2-4} +```js filename="content/_meta.js" {2-4} export default { '*': { type: 'page' @@ -323,7 +323,7 @@ export default { You can configure the theme for each page using the `"theme"` option. For example, you can disable or enable specific components for specific pages: -```js filename="pages/_meta.js" +```js filename="content/_meta.js" export default { index: { title: 'Home', @@ -350,7 +350,7 @@ the default behavior. You might want to render some page with the full container width and height, but keep all the other styles. You can use the `"full"` layout to do that: -```js filename="pages/_meta.js" {5} +```js filename="content/_meta.js" {5} export default { index: { title: 'Home', @@ -370,7 +370,7 @@ heading styles and components like `li` and `code`. There are `"default"` and The default one is suitable for most cases like documentation, but you can use the `"article"` typesetting to make it look like an elegant article page: -```js filename="pages/_meta.js" {5} +```js filename="content/_meta.js" {5} export default { about: { title: 'About Us', From 8a8da29e527e17c0551fffeedabfb8063f286d7a Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 02:27:43 +0300 Subject: [PATCH 10/40] more --- docs/app/docs/guide/custom-css/page.mdx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/docs/app/docs/guide/custom-css/page.mdx b/docs/app/docs/guide/custom-css/page.mdx index 3ecd91cb85..15a56f4218 100644 --- a/docs/app/docs/guide/custom-css/page.mdx +++ b/docs/app/docs/guide/custom-css/page.mdx @@ -21,14 +21,13 @@ body { } ``` -You can create a `pages/_app.js` file and import your CSS files there: +Import your CSS files in root layout: -```jsx filename="pages/_app.js" -import '../styles.css' +```jsx filename="app/layout.jsx" +import '../path/to/your/styles.css' -// This default export is required in a new `pages/_app.js` file. -export default function MyApp({ Component, pageProps }) { - return +export default async function RootLayout({ children }) { + // ... } ``` From 98c1c0df5e7354fc1be98a8262ff03d96e966284 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 02:28:58 +0300 Subject: [PATCH 11/40] more --- docs/app/docs/guide/organize-files/page.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/app/docs/guide/organize-files/page.mdx b/docs/app/docs/guide/organize-files/page.mdx index b526078d94..6facb3c68b 100644 --- a/docs/app/docs/guide/organize-files/page.mdx +++ b/docs/app/docs/guide/organize-files/page.mdx @@ -65,7 +65,7 @@ directory, and it will be used to override the default configuration of each page: - + @@ -140,7 +140,7 @@ It tells Nextra the order of each page, and the correct title. Alternatively, you can do it with `title` property and have other configurations in there as well: -```js filename="pages/_meta.js" +```js filename="content/_meta.js" export default { index: 'My Homepage', contact: 'Contact Us', From 31ee3248212ef07b3072396515f2bffff135e896 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 03:09:12 +0300 Subject: [PATCH 12/40] more --- docs/app/docs/built-ins/page.mdx | 64 +++++-------------- packages/nextra/src/server/page-map/get.ts | 24 ++++++- .../nextra/src/server/page-map/index-page.ts | 41 ++++++++++++ packages/nextra/src/server/page-map/index.ts | 1 + .../nextra/src/server/page-map/placeholder.ts | 5 -- 5 files changed, 78 insertions(+), 57 deletions(-) create mode 100644 packages/nextra/src/server/page-map/index-page.ts diff --git a/docs/app/docs/built-ins/page.mdx b/docs/app/docs/built-ins/page.mdx index f71e92cf00..3b3d8a2292 100644 --- a/docs/app/docs/built-ins/page.mdx +++ b/docs/app/docs/built-ins/page.mdx @@ -11,60 +11,26 @@ import { TableIcon, WarningIcon } from '@components/icons' -import { compileMdx } from 'nextra/compile' import { Cards } from 'nextra/components' import { MDXRemote } from 'nextra/mdx-remote' -import { getPageMap } from 'nextra/page-map' +import { createIndexPage, getPageMap } from 'nextra/page-map' # Built-ins Nextra includes a couple of built-in components that you can use to better style your content: -export async function List() { - const pageMap = await getPageMap() - const [_meta, ...pages] = pageMap - .find(item => item.name === 'docs') - .children.find(item => item.name === 'built-ins').children - const layoutIndex = pages.findIndex(item => item.type === 'separator') - const contentIndex = pages.findLastIndex(item => item.type === 'separator') - function renderCard(item) { - const { icon, sidebarTitle } = item.frontMatter - const Icon = icon ? `<${icon}/>` : 'null' - return `` - } - const { result } = await compileMdx(`## ${pages[layoutIndex].title} - -${pages - .slice(layoutIndex + 1, contentIndex) - .map(renderCard) - .join('')} - -## ${pages[contentIndex].title} - -${pages - .slice(contentIndex + 1) - .map(renderCard) - .join('')} -`) - return ( - - ) -} - - + diff --git a/packages/nextra/src/server/page-map/get.ts b/packages/nextra/src/server/page-map/get.ts index 4cbaae61ff..88f50fb875 100644 --- a/packages/nextra/src/server/page-map/get.ts +++ b/packages/nextra/src/server/page-map/get.ts @@ -1,9 +1,27 @@ -function importPageMap(lang = '') { +import { Folder, PageMapItem } from '../../types' + +function importPageMap(lang = ''): Promise<{ + pageMap: PageMapItem[] + RouteToFilepath: Record +}> { return import(`./placeholder.js?lang=${lang}`) } -export async function getPageMap(lang?: string) { - const { pageMap } = await importPageMap(lang) +export async function getPageMap(lang?: string, route = '/') { + let { pageMap } = await importPageMap(lang) + + const segments = route.split('/').filter(Boolean) + let segment: string | undefined + while ((segment = segments.shift())) { + const folder = pageMap.find( + (item): item is Folder => 'name' in item && item.name === segment + ) + if (!folder) { + throw new Error(`Can't find pageMap for "${segment}" in route "${route}"`) + } + pageMap = folder.children + } + return pageMap } diff --git a/packages/nextra/src/server/page-map/index-page.ts b/packages/nextra/src/server/page-map/index-page.ts new file mode 100644 index 0000000000..a1306ef70c --- /dev/null +++ b/packages/nextra/src/server/page-map/index-page.ts @@ -0,0 +1,41 @@ +import { MdxFile, PageMapItem } from '../../types' +import { compileMdx } from '../compile.js' + +function renderCard(item: MdxFile): string { + const { icon, sidebarTitle } = item.frontMatter! + const Icon = icon ? `<${icon}/>` : 'null' + return `` +} + +export async function createIndexPage(pageMap: PageMapItem[]): Promise { + let result = [] + let hasCards = false + for (const item of pageMap) { + if ('data' in item) { + continue + } + // @ts-expect-error fixme + if (item.type === 'separator') { + if (hasCards) { + result.push('') + hasCards = false + } + // @ts-expect-error fixme + result.push(`## ${item.title}`) + continue + } + if (!hasCards) { + hasCards = true + result.push('') + } + result.push(renderCard(item)) + } + if (hasCards) { + result.push('') + } + const rawJsx = result.join('\n') + + const mdx = await compileMdx(rawJsx) + + return mdx.result +} diff --git a/packages/nextra/src/server/page-map/index.ts b/packages/nextra/src/server/page-map/index.ts index b3ed1c8592..bca0ae4560 100644 --- a/packages/nextra/src/server/page-map/index.ts +++ b/packages/nextra/src/server/page-map/index.ts @@ -2,3 +2,4 @@ export { normalizePageMap } from './normalize.js' export { convertToPageMap } from './to-page-map.js' export { createCatchAllMeta } from './catch-all.js' export { getPageMap } from './get.js' +export { createIndexPage } from './index-page.js' diff --git a/packages/nextra/src/server/page-map/placeholder.ts b/packages/nextra/src/server/page-map/placeholder.ts index c95f5064d5..e69de29bb2 100644 --- a/packages/nextra/src/server/page-map/placeholder.ts +++ b/packages/nextra/src/server/page-map/placeholder.ts @@ -1,5 +0,0 @@ -import type { PageMapItem } from '../../types.js' - -export const pageMap: PageMapItem[] = [] - -export const RouteToFilepath: Record = {} From c3b94c646653e0f05c28c15cd6f78c3fe582c5db Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 03:14:13 +0300 Subject: [PATCH 13/40] more --- docs/app/docs/blog-theme/page.mdx | 18 +++++++++++------- docs/app/docs/blog-theme/start/page.mdx | 4 ++++ .../nextra/src/server/page-map/index-page.ts | 4 ++-- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/docs/app/docs/blog-theme/page.mdx b/docs/app/docs/blog-theme/page.mdx index b4473c08ed..2b71cd196c 100644 --- a/docs/app/docs/blog-theme/page.mdx +++ b/docs/app/docs/blog-theme/page.mdx @@ -5,13 +5,17 @@ sidebarTitle: Blog Theme import { ChevronRightIcon } from '@components/icons' import { Cards } from 'nextra/components' +import { MDXRemote } from 'nextra/mdx-remote' +import { createIndexPage, getPageMap } from 'nextra/page-map' # Nextra Blog Theme - - } - title="Get Started" - href="/docs/blog-theme/start" - /> - + diff --git a/docs/app/docs/blog-theme/start/page.mdx b/docs/app/docs/blog-theme/start/page.mdx index 08e14c01a0..ab6d11a2da 100644 --- a/docs/app/docs/blog-theme/start/page.mdx +++ b/docs/app/docs/blog-theme/start/page.mdx @@ -1,3 +1,7 @@ +--- +icon: ChevronRightIcon +--- + import InstallNextraTheme from '@components/install-nextra-theme.mdx' import ReadeToGo from '@components/ready-to-go.mdx' import { Steps } from 'nextra/components' diff --git a/packages/nextra/src/server/page-map/index-page.ts b/packages/nextra/src/server/page-map/index-page.ts index a1306ef70c..f88c9a29dd 100644 --- a/packages/nextra/src/server/page-map/index-page.ts +++ b/packages/nextra/src/server/page-map/index-page.ts @@ -2,9 +2,9 @@ import { MdxFile, PageMapItem } from '../../types' import { compileMdx } from '../compile.js' function renderCard(item: MdxFile): string { - const { icon, sidebarTitle } = item.frontMatter! + const { icon, sidebarTitle, title } = item.frontMatter! const Icon = icon ? `<${icon}/>` : 'null' - return `` + return `` } export async function createIndexPage(pageMap: PageMapItem[]): Promise { From a8db331b36fca3e274116840665960ea00fd2d3e Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 03:23:47 +0300 Subject: [PATCH 14/40] more --- .../customize-the-cascade-layers/page.mdx | 4 ++ docs/app/docs/advanced/latex/page.mdx | 4 ++ docs/app/docs/advanced/mermaid/page.mdx | 4 ++ docs/app/docs/advanced/npm2yarn/page.mdx | 4 ++ docs/app/docs/advanced/page.mdx | 60 ++++++------------- docs/app/docs/advanced/remote/page.mdx | 4 ++ docs/app/docs/advanced/table/page.mdx | 4 ++ docs/app/docs/advanced/tailwind-css/page.mdx | 4 ++ docs/app/docs/advanced/typescript/page.mdx | 4 ++ 9 files changed, 49 insertions(+), 43 deletions(-) diff --git a/docs/app/docs/advanced/customize-the-cascade-layers/page.mdx b/docs/app/docs/advanced/customize-the-cascade-layers/page.mdx index 3443fb526a..4b8942e2a4 100644 --- a/docs/app/docs/advanced/customize-the-cascade-layers/page.mdx +++ b/docs/app/docs/advanced/customize-the-cascade-layers/page.mdx @@ -1,3 +1,7 @@ +--- +sidebarTitle: Customize Cascade Layers +--- + import { Steps } from 'nextra/components' # Customize the Cascade Layers diff --git a/docs/app/docs/advanced/latex/page.mdx b/docs/app/docs/advanced/latex/page.mdx index 1ccac040ce..8f9d56da47 100644 --- a/docs/app/docs/advanced/latex/page.mdx +++ b/docs/app/docs/advanced/latex/page.mdx @@ -1,3 +1,7 @@ +--- +icon: FormulaIcon +--- + import { compileMdx } from 'nextra/compile' import { MDXRemote } from 'nextra/mdx-remote' import { diff --git a/docs/app/docs/advanced/mermaid/page.mdx b/docs/app/docs/advanced/mermaid/page.mdx index 61acc9a798..175c102583 100644 --- a/docs/app/docs/advanced/mermaid/page.mdx +++ b/docs/app/docs/advanced/mermaid/page.mdx @@ -1,3 +1,7 @@ +--- +icon: DiagramIcon +--- + import { compileMdx } from 'nextra/compile' import { Mermaid } from 'nextra/components' import { MDXRemote } from 'nextra/mdx-remote' diff --git a/docs/app/docs/advanced/npm2yarn/page.mdx b/docs/app/docs/advanced/npm2yarn/page.mdx index a7f7ee99ef..a6f6dab674 100644 --- a/docs/app/docs/advanced/npm2yarn/page.mdx +++ b/docs/app/docs/advanced/npm2yarn/page.mdx @@ -1,3 +1,7 @@ +--- +icon: TerminalIcon +--- + import { compileMdx } from 'nextra/compile' import { Tabs } from 'nextra/components' import { MDXRemote } from 'nextra/mdx-remote' diff --git a/docs/app/docs/advanced/page.mdx b/docs/app/docs/advanced/page.mdx index 7808d9f9a3..219d796894 100644 --- a/docs/app/docs/advanced/page.mdx +++ b/docs/app/docs/advanced/page.mdx @@ -11,49 +11,23 @@ import { } from '@components/icons' import { Cards } from 'nextra/components' import { TerminalIcon, TypeScriptIcon } from 'nextra/icons' +import { MDXRemote } from 'nextra/mdx-remote' +import { createIndexPage, getPageMap } from 'nextra/page-map' # Advanced - - } - title="Npm2Yarn" - href="/docs/advanced/npm2yarn" - /> - } - title="Mermaid" - href="/docs/advanced/mermaid" - /> - } - title="Tailwind CSS" - href="/docs/advanced/tailwind-css" - /> - } - title="LaTeX" - href="/docs/advanced/latex" - /> - } - title="Rendering Tables" - href="/docs/advanced/table" - /> - } - title="TypeScript" - href="/docs/advanced/typescript" - /> - } - title="Remote Content" - href="/docs/advanced/remote" - /> - - - - + diff --git a/docs/app/docs/advanced/remote/page.mdx b/docs/app/docs/advanced/remote/page.mdx index 36794c1773..4c19e68679 100644 --- a/docs/app/docs/advanced/remote/page.mdx +++ b/docs/app/docs/advanced/remote/page.mdx @@ -1,3 +1,7 @@ +--- +icon: CloudIcon +--- + # Remote Content import { Callout } from 'nextra/components' diff --git a/docs/app/docs/advanced/table/page.mdx b/docs/app/docs/advanced/table/page.mdx index de65a5080e..471df7c184 100644 --- a/docs/app/docs/advanced/table/page.mdx +++ b/docs/app/docs/advanced/table/page.mdx @@ -1,3 +1,7 @@ +--- +icon: TableIcon +--- + import { Callout, Table } from 'nextra/components' # Rendering Tables diff --git a/docs/app/docs/advanced/tailwind-css/page.mdx b/docs/app/docs/advanced/tailwind-css/page.mdx index 19d4749445..9b88a640f2 100644 --- a/docs/app/docs/advanced/tailwind-css/page.mdx +++ b/docs/app/docs/advanced/tailwind-css/page.mdx @@ -1,3 +1,7 @@ +--- +icon: TailwindIcon +--- + import { Steps } from 'nextra/components' # Tailwind CSS diff --git a/docs/app/docs/advanced/typescript/page.mdx b/docs/app/docs/advanced/typescript/page.mdx index 16ff591fc3..ca43f1662f 100644 --- a/docs/app/docs/advanced/typescript/page.mdx +++ b/docs/app/docs/advanced/typescript/page.mdx @@ -1,3 +1,7 @@ +--- +icon: TypeScriptIcon +--- + import { Steps } from 'nextra/components' # TypeScript From 7fa1d394505b0d255d6ef3e63a57922b70c22dee Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 03:36:51 +0300 Subject: [PATCH 15/40] moree --- docs/app/docs/advanced/page.mdx | 4 +- docs/app/docs/docs-theme/_meta.ts | 2 +- docs/app/docs/docs-theme/built-ins/page.mdx | 18 +++++++++ .../docs-theme/page-configuration/page.mdx | 4 ++ docs/app/docs/docs-theme/page.mdx | 37 +++++++------------ docs/app/docs/docs-theme/start/page.mdx | 7 ++-- docs/next.config.ts | 5 --- 7 files changed, 41 insertions(+), 36 deletions(-) create mode 100644 docs/app/docs/docs-theme/built-ins/page.mdx diff --git a/docs/app/docs/advanced/page.mdx b/docs/app/docs/advanced/page.mdx index 219d796894..a618cea70c 100644 --- a/docs/app/docs/advanced/page.mdx +++ b/docs/app/docs/advanced/page.mdx @@ -17,9 +17,7 @@ import { createIndexPage, getPageMap } from 'nextra/page-map' # Advanced diff --git a/docs/app/docs/docs-theme/page-configuration/page.mdx b/docs/app/docs/docs-theme/page-configuration/page.mdx index 0adddd8de1..cd2b94cc8b 100644 --- a/docs/app/docs/docs-theme/page-configuration/page.mdx +++ b/docs/app/docs/docs-theme/page-configuration/page.mdx @@ -1,3 +1,7 @@ +--- +icon: RowsIcon +--- + import { Screenshot } from 'components/screenshot' import { Video } from 'components/video' import { FileTree } from 'nextra/components' diff --git a/docs/app/docs/docs-theme/page.mdx b/docs/app/docs/docs-theme/page.mdx index 2e0f75d572..416a90cf0f 100644 --- a/docs/app/docs/docs-theme/page.mdx +++ b/docs/app/docs/docs-theme/page.mdx @@ -8,31 +8,20 @@ sidebarTitle: Docs Theme import { BoxIcon, ChevronRightIcon, - GearIcon, RowsIcon } from '@components/icons' import { Cards } from 'nextra/components' +import { MDXRemote } from 'nextra/mdx-remote' +import { createIndexPage, getPageMap } from 'nextra/page-map' - - } - title="Get Started" - href="/docs/docs-theme/start" - /> - } - title="Page Configuration" - href="/docs/docs-theme/page-configuration" - /> - } - title="Theme Configuration" - href="/docs/docs-theme/theme-configuration" - /> - } - title="Built-in Components" - href="/docs/docs-theme/built-ins" - /> - - + diff --git a/docs/app/docs/docs-theme/start/page.mdx b/docs/app/docs/docs-theme/start/page.mdx index 9432596a59..82adaade33 100644 --- a/docs/app/docs/docs-theme/start/page.mdx +++ b/docs/app/docs/docs-theme/start/page.mdx @@ -1,6 +1,7 @@ -export const metadata = { - sidebarTitle: 'Get Started' -} +--- +sidebarTitle: Get Started +icon: ChevronRightIcon +--- import InstallNextraTheme from '@components/install-nextra-theme.mdx' import ReadeToGo from '@components/ready-to-go.mdx' diff --git a/docs/next.config.ts b/docs/next.config.ts index 51f1abd09d..013adbec8c 100644 --- a/docs/next.config.ts +++ b/docs/next.config.ts @@ -27,11 +27,6 @@ const nextConfig = withNextra({ destination: '/docs/docs-theme/api', permanent: true }, - { - source: '/docs/docs-theme/built-ins', - destination: '/docs/built-ins', - permanent: true - }, { source: '/docs/guide/advanced/:slug', destination: '/docs/advanced/:slug', From e43841bdad799d8c94ced21be14ab64455adebc5 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 03:37:08 +0300 Subject: [PATCH 16/40] moree --- docs/app/docs/docs-theme/page.mdx | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/docs/app/docs/docs-theme/page.mdx b/docs/app/docs/docs-theme/page.mdx index 416a90cf0f..5ee27983ad 100644 --- a/docs/app/docs/docs-theme/page.mdx +++ b/docs/app/docs/docs-theme/page.mdx @@ -5,23 +5,19 @@ sidebarTitle: Docs Theme # Nextra Docs Theme -import { - BoxIcon, - ChevronRightIcon, - RowsIcon -} from '@components/icons' +import { BoxIcon, ChevronRightIcon, RowsIcon } from '@components/icons' import { Cards } from 'nextra/components' import { MDXRemote } from 'nextra/mdx-remote' import { createIndexPage, getPageMap } from 'nextra/page-map' From ebb77254f818b60bc244ebc5e0466192e29de22f Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 03:48:41 +0300 Subject: [PATCH 17/40] moree --- docs/app/docs/guide/custom-css/page.mdx | 7 +- docs/app/docs/guide/i18n/page.mdx | 4 + docs/app/docs/guide/image/page.mdx | 4 + docs/app/docs/guide/link/page.mdx | 4 + docs/app/docs/guide/markdown/page.mdx | 4 + docs/app/docs/guide/organize-files/page.mdx | 4 + docs/app/docs/guide/page.mdx | 76 +++++-------------- docs/app/docs/guide/ssg/page.mdx | 4 + .../docs/guide/syntax-highlighting/page.mdx | 4 + 9 files changed, 52 insertions(+), 59 deletions(-) diff --git a/docs/app/docs/guide/custom-css/page.mdx b/docs/app/docs/guide/custom-css/page.mdx index 15a56f4218..3ba40da2ea 100644 --- a/docs/app/docs/guide/custom-css/page.mdx +++ b/docs/app/docs/guide/custom-css/page.mdx @@ -1,6 +1,7 @@ -export const metadata = { - sidebarTitle: 'Custom CSS' -} +--- +sidebarTitle: Custom CSS +icon: BrushIcon +--- # Custom CSS Support diff --git a/docs/app/docs/guide/i18n/page.mdx b/docs/app/docs/guide/i18n/page.mdx index 38f8baa549..9aebe8a67f 100644 --- a/docs/app/docs/guide/i18n/page.mdx +++ b/docs/app/docs/guide/i18n/page.mdx @@ -1,3 +1,7 @@ +--- +icon: GlobeIcon +--- + import { Steps } from 'nextra/components' # Next.js I18n diff --git a/docs/app/docs/guide/image/page.mdx b/docs/app/docs/guide/image/page.mdx index dfa294787d..a2f550c6fd 100644 --- a/docs/app/docs/guide/image/page.mdx +++ b/docs/app/docs/guide/image/page.mdx @@ -1,3 +1,7 @@ +--- +icon: PictureIcon +--- + # Next.js Image The standard way to use diff --git a/docs/app/docs/guide/link/page.mdx b/docs/app/docs/guide/link/page.mdx index 1292ed67d2..8abc81e216 100644 --- a/docs/app/docs/guide/link/page.mdx +++ b/docs/app/docs/guide/link/page.mdx @@ -1,3 +1,7 @@ +--- +icon: LinkIcon +--- + # Next.js Link All relative Markdown links are automatically converted to diff --git a/docs/app/docs/guide/markdown/page.mdx b/docs/app/docs/guide/markdown/page.mdx index 0930a8e4b5..8ab44d3cce 100644 --- a/docs/app/docs/guide/markdown/page.mdx +++ b/docs/app/docs/guide/markdown/page.mdx @@ -1,3 +1,7 @@ +--- +icon: MarkdownIcon +--- + import { Shadow } from '@components/utils/shadow' import { Counter } from './_counter' diff --git a/docs/app/docs/guide/organize-files/page.mdx b/docs/app/docs/guide/organize-files/page.mdx index 6facb3c68b..2798c40932 100644 --- a/docs/app/docs/guide/organize-files/page.mdx +++ b/docs/app/docs/guide/organize-files/page.mdx @@ -1,3 +1,7 @@ +--- +icon: FilesIcon +--- + import { FileIcon, NewsletterIcon } from '@components/icons' import { Cards, FileTree } from 'nextra/components' diff --git a/docs/app/docs/guide/page.mdx b/docs/app/docs/guide/page.mdx index 1b0f4312d5..c28f7ac6f6 100644 --- a/docs/app/docs/guide/page.mdx +++ b/docs/app/docs/guide/page.mdx @@ -1,7 +1,9 @@ +--- +asIndexPage: true +--- + import { - BoxIcon, BrushIcon, - DropperIcon, FilesIcon, GlobeIcon, LightningIcon, @@ -11,63 +13,25 @@ import { } from '@components/icons' import { Cards } from 'nextra/components' import { MarkdownIcon } from 'nextra/icons' - -export const metadata = { - asIndexPage: true -} +import { MDXRemote } from 'nextra/mdx-remote' +import { createIndexPage, getPageMap } from 'nextra/page-map' # Guide The following features are configured via the Next.js configuration and are available in all themes. - - } - title="Organize Files" - href="/docs/guide/organize-files" - /> - } - title="Markdown" - href="/docs/guide/markdown" - /> - } - title="Syntax Highlighting" - href="/docs/guide/syntax-highlighting" - /> - } - title="Next.js Link" - href="/docs/guide/link" - /> - } - title="Next.js Image" - href="/docs/guide/image" - /> - } - title="Next.js SSG" - href="/docs/guide/ssg" - /> - } - title="Next.js I18n" - href="/docs/guide/i18n" - /> - } - title="Custom CSS" - href="/docs/guide/custom-css" - /> - - - } - title="Built-in Components" - href="/docs/built-ins" - /> - } title="Advanced" href="/docs/advanced" /> - + diff --git a/docs/app/docs/guide/ssg/page.mdx b/docs/app/docs/guide/ssg/page.mdx index 0df4084ca1..ca7f4d4d57 100644 --- a/docs/app/docs/guide/ssg/page.mdx +++ b/docs/app/docs/guide/ssg/page.mdx @@ -1,3 +1,7 @@ +--- +icon: LightningIcon +--- + import { compileMdx } from 'nextra/compile' import { Callout } from 'nextra/components' import { MDXRemote } from 'nextra/mdx-remote' diff --git a/docs/app/docs/guide/syntax-highlighting/page.mdx b/docs/app/docs/guide/syntax-highlighting/page.mdx index b502532f0d..71f7484449 100644 --- a/docs/app/docs/guide/syntax-highlighting/page.mdx +++ b/docs/app/docs/guide/syntax-highlighting/page.mdx @@ -1,3 +1,7 @@ +--- +icon: StarsIcon +--- + import { OptionTable } from 'components/_table' import { compileMdx } from 'nextra/compile' import { MDXRemote } from 'nextra/mdx-remote' From 4c71e7e3fa20f93b0ff417b2aa8eb5e0b0c01b17 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 03:52:15 +0300 Subject: [PATCH 18/40] moree --- docs/app/docs/guide/organize-files/page.mdx | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/docs/app/docs/guide/organize-files/page.mdx b/docs/app/docs/guide/organize-files/page.mdx index 2798c40932..326da00bfc 100644 --- a/docs/app/docs/guide/organize-files/page.mdx +++ b/docs/app/docs/guide/organize-files/page.mdx @@ -2,8 +2,7 @@ icon: FilesIcon --- -import { FileIcon, NewsletterIcon } from '@components/icons' -import { Cards, FileTree } from 'nextra/components' +import { FileTree } from 'nextra/components' # Organize Files @@ -156,20 +155,3 @@ export default { ``` The extra configurations are passed to the **theme** as additional information. -Check the corresponding pages for more information: - - - } - title="Docs Theme" - href="/docs/docs-theme/page-configuration" - arrow - /> - } - title="Blog Theme" - href="/docs/blog-theme/start" - arrow - /> - - From da82c73cfeea161ad50ac41921d054f732bc29de Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 08:48:36 +0300 Subject: [PATCH 19/40] moree --- examples/swr-site/app/_components/blog.tsx | 61 +++++++++----------- examples/swr-site/content/en/blog/swr-v1.mdx | 2 +- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/examples/swr-site/app/_components/blog.tsx b/examples/swr-site/app/_components/blog.tsx index 1a8a3458f0..97bc3072ce 100644 --- a/examples/swr-site/app/_components/blog.tsx +++ b/examples/swr-site/app/_components/blog.tsx @@ -1,41 +1,34 @@ -import Link from 'next/link' +import type { MdxFile } from 'nextra' +import { Link } from 'nextra-theme-docs' import { getPageMap } from 'nextra/page-map' import type { FC } from 'react' export const Blog: FC<{ lang: string }> = async ({ lang }) => { - const pageMap = await getPageMap(lang) - const blogItems = pageMap.find(item => item.name === 'blog').children + const pageMap = (await getPageMap(lang, '/blog')) as unknown as MdxFile[] + return pageMap.map(page => { + if (page.name === 'index') return + const { title, description, date } = page.frontMatter! - return blogItems.map( - page => - page.route?.startsWith('/blog/') && ( -
- - {page.frontMatter.title} + return ( +
+

{title}

+

+ {description}{' '} + + Read more -

- {page.frontMatter.description} - - Read more → - -

- -
- ) - ) +

+ +
+ ) + }) } diff --git a/examples/swr-site/content/en/blog/swr-v1.mdx b/examples/swr-site/content/en/blog/swr-v1.mdx index fc7257100e..6d18702526 100644 --- a/examples/swr-site/content/en/blog/swr-v1.mdx +++ b/examples/swr-site/content/en/blog/swr-v1.mdx @@ -4,7 +4,7 @@ image: https://assets.vercel.com/image/upload/v1630059453/swr/v1.png description: 'Almost 2 years ago we open sourced SWR, the tiny data-fetching React library that people love. Today we are reaching another milestone: the 1.0 version of - SWR' + SWR!' date: 2021-08-27 authors: - name: Shu Ding From 7bdefb3f97e4618c59b77c9aa6637c5ffcbec294 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 08:52:24 +0300 Subject: [PATCH 20/40] moree --- examples/blog/app/posts/get-posts.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/blog/app/posts/get-posts.js b/examples/blog/app/posts/get-posts.js index e63dad3a83..db2e34cf52 100644 --- a/examples/blog/app/posts/get-posts.js +++ b/examples/blog/app/posts/get-posts.js @@ -1,10 +1,9 @@ import { getPageMap } from 'nextra/page-map' export async function getPosts() { - const pageMap = await getPageMap() + const pageMap = await getPageMap('', '/posts') return pageMap - .find(item => item.route === '/posts') - .children.filter(post => !post.frontMatter.draft && post.name !== 'index') + .filter(post => !post.frontMatter.draft && post.name !== 'index') .sort((a, b) => new Date(b.frontMatter.date) - new Date(a.frontMatter.date)) } From 6021ee0e422139ba5fe1136051e2eccc7332a6bb Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 11:58:06 +0300 Subject: [PATCH 21/40] moree --- packages/nextra/src/server/compile.ts | 21 ++++++------ packages/nextra/src/server/loader.ts | 18 +++-------- .../nextra/src/server/remark-plugins/index.ts | 1 + .../remark-assign-frontmatter.ts | 32 +++++++++++++++++++ .../remark-plugins/remark-mdx-frontmatter.ts | 13 +++----- .../server/remark-plugins/remark-mdx-title.ts | 6 ++-- 6 files changed, 56 insertions(+), 35 deletions(-) create mode 100644 packages/nextra/src/server/remark-plugins/remark-assign-frontmatter.ts diff --git a/packages/nextra/src/server/compile.ts b/packages/nextra/src/server/compile.ts index 8d4e8fb81d..f027b5e9c6 100644 --- a/packages/nextra/src/server/compile.ts +++ b/packages/nextra/src/server/compile.ts @@ -28,6 +28,7 @@ import { rehypeTwoslashPopup } from './rehype-plugins/index.js' import { + remarkAssignFrontMatter, remarkCustomHeadingId, remarkHeadings, remarkLinkRewrite, @@ -59,10 +60,11 @@ type CompileMdxOptions = Pick< | 'codeHighlight' | 'whiteListTagsStyling' > & { - mdxOptions?: MdxOptions - filePath?: string - useCachedCompiler?: boolean - isPageImport?: boolean + mdxOptions: MdxOptions + filePath: string + useCachedCompiler: boolean + isPageImport: boolean + lastCommitTime: number } export async function compileMdx( @@ -78,12 +80,12 @@ export async function compileMdx( filePath = '', useCachedCompiler, isPageImport = true, - whiteListTagsStyling = [] + whiteListTagsStyling = [], + lastCommitTime }: Partial = {} ): Promise<{ result: string title?: string - readingTime?: ReadingTime frontMatter: FrontMatter }> { const { @@ -124,12 +126,11 @@ export async function compileMdx( const vFile = await processor.process(fileCompatible) const data = vFile.data as { - readingTime?: ReadingTime title?: string frontMatter: FrontMatter } - const { readingTime, title, frontMatter } = data + const { title, frontMatter } = data // https://github.com/shuding/nextra/issues/1032 const result = String(vFile).replaceAll('__esModule', '_\\_esModule') @@ -147,7 +148,6 @@ export async function compileMdx( return { result, title, - ...(readingTime && { readingTime }), frontMatter } } catch (error) { @@ -177,6 +177,8 @@ export async function compileMdx( isRemoteContent && remarkRemoveImports, remarkFrontmatter, // parse and attach yaml node remarkMdxFrontMatter, + readingTime && remarkReadingTime, + [remarkAssignFrontMatter, { lastCommitTime }] satisfies Pluggable, remarkGfm, format !== 'md' && ([ @@ -188,7 +190,6 @@ export async function compileMdx( remarkMdxTitle, [remarkHeadings, { isRemoteContent }] satisfies Pluggable, staticImage && remarkStaticImage, - readingTime && remarkReadingTime, latex && remarkMath, // Remove the markdown file extension from links [ diff --git a/packages/nextra/src/server/loader.ts b/packages/nextra/src/server/loader.ts index 9bb37d676d..6f9e4cf603 100644 --- a/packages/nextra/src/server/loader.ts +++ b/packages/nextra/src/server/loader.ts @@ -115,8 +115,7 @@ export async function loader( const rawJs = await compileMetadata(source, { filePath }) return rawJs } - - const { result, readingTime } = await compileMdx(source, { + const { result } = await compileMdx(source, { mdxOptions: { ...mdxOptions, jsx: true, @@ -143,28 +142,19 @@ export async function loader( filePath, useCachedCompiler: true, isPageImport, - whiteListTagsStyling - }) - - const restProps: PageOpts['metadata'] = { - filePath: slash(path.relative(CWD, filePath)), + whiteListTagsStyling, // Run only on production because it can slow down Fast Refresh for uncommitted files // https://github.com/shuding/nextra/issues/3675#issuecomment-2466416366 - timestamp: IS_PRODUCTION ? await getLastCommitTime(filePath) : NOW, - readingTime - } - const enhancedMetadata = `Object.assign(metadata, ${JSON.stringify(restProps)})` + lastCommitTime: IS_PRODUCTION ? await getLastCommitTime(filePath) : NOW + }) // Imported as a normal component, no need to add the layout. if (!isPageImport) { return `${result} -${enhancedMetadata} export default MDXLayout` } const rawJs = `import { HOC_MDXWrapper } from 'nextra/setup-page' ${result} - -${enhancedMetadata} export default HOC_MDXWrapper( MDXLayout, {metadata, title, toc:useTOC()} diff --git a/packages/nextra/src/server/remark-plugins/index.ts b/packages/nextra/src/server/remark-plugins/index.ts index ec237f8c9a..f6efa9b849 100644 --- a/packages/nextra/src/server/remark-plugins/index.ts +++ b/packages/nextra/src/server/remark-plugins/index.ts @@ -10,3 +10,4 @@ export { } from './remark-link-rewrite.js' export { remarkMdxDisableExplicitJsx } from './remark-mdx-disable-explicit-jsx.js' export { remarkStaticImage } from './remark-static-image.js' +export { remarkAssignFrontMatter } from './remark-assign-frontmatter.js' diff --git a/packages/nextra/src/server/remark-plugins/remark-assign-frontmatter.ts b/packages/nextra/src/server/remark-plugins/remark-assign-frontmatter.ts new file mode 100644 index 0000000000..8da2b0c77f --- /dev/null +++ b/packages/nextra/src/server/remark-plugins/remark-assign-frontmatter.ts @@ -0,0 +1,32 @@ +import path from 'node:path' +import { Property } from 'estree' +import { valueToEstree } from 'estree-util-value-to-estree' +import type { Root } from 'mdast' +import slash from 'slash' +import type { Plugin } from 'unified' +import { ReadingTime } from '../../types.js' +import { CWD } from '../constants.js' +import { getFrontMatterASTObject, isExportNode } from './remark-mdx-title.js' + +export const remarkAssignFrontMatter: Plugin< + [{ lastCommitTime?: number }], + Root +> = + ({ lastCommitTime }) => + (ast, file) => { + const frontMatterNode = ast.children.find((node: any) => + isExportNode(node, 'metadata') + )! + const frontMatter = getFrontMatterASTObject(frontMatterNode) + + const [filePath] = file.history + const { readingTime } = file.data as { readingTime?: ReadingTime } + + const { properties } = valueToEstree({ + // File path can be undefined (e.g. dynamic mdx without filePath provided to processor) + ...(filePath && { filePath: slash(path.relative(CWD, filePath)) }), + ...(readingTime && { readingTime }), + ...(lastCommitTime && { timestamp: lastCommitTime }) + }) as { properties: Property[] } + frontMatter.push(...properties) + } diff --git a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts index 5dcb95aa3a..112d991645 100644 --- a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts +++ b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts @@ -5,7 +5,7 @@ import type { Parent, Root } from 'mdast' import type { Plugin } from 'unified' import { parse as parseYaml } from 'yaml' import { createAstExportConst } from '../utils.js' -import { isExportNode } from './remark-mdx-title.js' +import { isExportNode, getFrontMatterASTObject } from './remark-mdx-title.js' function createNode(data: Record) { return { @@ -43,13 +43,10 @@ export const remarkMdxFrontMatter: Plugin<[], Root> = ast.children.unshift(createNode({})) } - // @ts-expect-error -- fixme - const frontMatter = ast.children.find( - node => - // @ts-expect-error -- fixme - isExportNode(node, 'metadata') - // @ts-expect-error -- fixme - ).data.estree.body[0].declaration.declarations[0].init.properties + const frontMatterNode = ast.children.find((node: any) => + isExportNode(node, 'metadata') + )! + const frontMatter = getFrontMatterASTObject(frontMatterNode) file.data.frontMatter = estreeToValue(frontMatter) } diff --git a/packages/nextra/src/server/remark-plugins/remark-mdx-title.ts b/packages/nextra/src/server/remark-plugins/remark-mdx-title.ts index 16e304aba9..cca577c3c0 100644 --- a/packages/nextra/src/server/remark-plugins/remark-mdx-title.ts +++ b/packages/nextra/src/server/remark-plugins/remark-mdx-title.ts @@ -8,7 +8,7 @@ import { DEFAULT_PROPERTY_PROPS } from '../constants.js' import { createAstExportConst, pageTitleFromFilename } from '../utils.js' import { getFlattenedValue } from './remark-headings.js' -function getFrontMatterASTObject(node: MdxjsEsm): Property[] { +export function getFrontMatterASTObject(node: MdxjsEsm): Property[] { const [n] = node.data!.estree!.body return (n as any).declaration.declarations[0].init.properties } @@ -33,8 +33,8 @@ export const remarkMdxTitle: Plugin<[], Root> = () => (ast, file) => { const frontMatterNode = ast.children.find((node: any) => isExportNode(node, 'metadata') - ) - const frontMatter = getFrontMatterASTObject(frontMatterNode as any) + )! + const frontMatter = getFrontMatterASTObject(frontMatterNode) for (const { key, value } of frontMatter) { if (key.type === 'Literal' && key.value === 'title') { From bff02d56482065cc11e9a682337c0a8c1e05ac4d Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 12:21:23 +0300 Subject: [PATCH 22/40] moree --- docs/app/docs/advanced/latex/page.mdx | 4 +- docs/app/docs/advanced/mermaid/page.mdx | 4 +- docs/app/docs/advanced/npm2yarn/page.mdx | 4 +- docs/app/docs/built-ins/cards/page.mdx | 4 +- docs/app/docs/guide/ssg/page.mdx | 4 +- .../docs/guide/syntax-highlighting/page.mdx | 4 +- docs/components/toggle-visibility-section.tsx | 4 +- examples/docs/src/content/features/mdx.mdx | 4 +- .../graphql-eslint/[[...slug]]/page.tsx | 4 +- .../remote/graphql-yoga/[[...slug]]/page.tsx | 4 +- packages/nextra/__test__/compile.test.ts | 105 +++++++++--------- packages/nextra/__test__/latex.test.ts | 16 +-- .../src/client/components/playground.tsx | 4 +- packages/nextra/src/server/loader.ts | 6 +- .../nextra/src/server/page-map/index-page.ts | 6 +- .../rehype-extract-toc-content.test.ts | 22 ++-- .../__tests__/remark-mdx-title.test.ts | 20 ++-- .../__tests__/remark-remove-imports.test.ts | 4 +- .../__tests__/remark-static-images.test.ts | 8 +- .../remark-plugins/remark-mdx-frontmatter.ts | 4 +- 20 files changed, 117 insertions(+), 118 deletions(-) diff --git a/docs/app/docs/advanced/latex/page.mdx b/docs/app/docs/advanced/latex/page.mdx index 8f9d56da47..0e5eb37ace 100644 --- a/docs/app/docs/advanced/latex/page.mdx +++ b/docs/app/docs/advanced/latex/page.mdx @@ -189,7 +189,7 @@ export async function MathJaxExample() { \\int_2^3x^3\\,\\mathrm{d}x ~~~ ` - const { result } = await compileMdx( + const rawJs = await compileMdx( rawMdx, { latex: { @@ -207,5 +207,5 @@ export async function MathJaxExample() { } ) - return + return } diff --git a/docs/app/docs/advanced/mermaid/page.mdx b/docs/app/docs/advanced/mermaid/page.mdx index 175c102583..0ea4c274a8 100644 --- a/docs/app/docs/advanced/mermaid/page.mdx +++ b/docs/app/docs/advanced/mermaid/page.mdx @@ -39,7 +39,7 @@ Z --> E; Z --> F; Z --> G; \`\`\`` - const { result } = await compileMdx(`${mermaidCodeblock} + const rawJs = await compileMdx(`${mermaidCodeblock} ## Usage @@ -47,5 +47,5 @@ Z --> G; ${mermaidCodeblock} ~~~ `) - return + return } diff --git a/docs/app/docs/advanced/npm2yarn/page.mdx b/docs/app/docs/advanced/npm2yarn/page.mdx index a6f6dab674..fcd7f2b2ba 100644 --- a/docs/app/docs/advanced/npm2yarn/page.mdx +++ b/docs/app/docs/advanced/npm2yarn/page.mdx @@ -25,11 +25,11 @@ export async function Page() { const codeBlock = `\`\`\`sh npm2yarn npm i -D @graphql-eslint/eslint-plugin \`\`\`` - const { result } = await compileMdx(`${codeBlock} + const rawJs = await compileMdx(`${codeBlock} ## Usage ~~~md filename="Markdown" /npm2yarn/ ${codeBlock} ~~~`) - return + return } diff --git a/docs/app/docs/built-ins/cards/page.mdx b/docs/app/docs/built-ins/cards/page.mdx index 102bab0bf6..aa842a6302 100644 --- a/docs/app/docs/built-ins/cards/page.mdx +++ b/docs/app/docs/built-ins/cards/page.mdx @@ -38,7 +38,7 @@ export async function CardsPage() { href="/docs/guide/built-ins/steps" /> ` - const { result } = await compileMdx(` + const rawJs = await compileMdx(` ## Grouped Cards ### Example @@ -76,7 +76,7 @@ ${mdx2} ~~~mdx filename="MDX" ${mdx2} ~~~`) - return + return } diff --git a/docs/app/docs/guide/ssg/page.mdx b/docs/app/docs/guide/ssg/page.mdx index ca7f4d4d57..3d7cdf2385 100644 --- a/docs/app/docs/guide/ssg/page.mdx +++ b/docs/app/docs/guide/ssg/page.mdx @@ -53,6 +53,6 @@ Here's the MDX code for the example above: ${starsComponent} ~~~ ` - const { result } = await compileMdx(mdx) - return + const rawJs = await compileMdx(mdx) + return } diff --git a/docs/app/docs/guide/syntax-highlighting/page.mdx b/docs/app/docs/guide/syntax-highlighting/page.mdx index 71f7484449..7d379799c2 100644 --- a/docs/app/docs/guide/syntax-highlighting/page.mdx +++ b/docs/app/docs/guide/syntax-highlighting/page.mdx @@ -173,7 +173,7 @@ export async function ANSI() {  PASS  Waiting for file changes... press h to show help, press q to quit \`\`\`` - const { result } = await compileMdx(`~~~md filename="Markdown" + const rawJs = await compileMdx(`~~~md filename="Markdown" ${rawAnsi} ~~~ @@ -181,7 +181,7 @@ Renders: ${rawAnsi} `) - return + return } ## Supported Languages diff --git a/docs/components/toggle-visibility-section.tsx b/docs/components/toggle-visibility-section.tsx index a15f147755..5ad1492368 100644 --- a/docs/components/toggle-visibility-section.tsx +++ b/docs/components/toggle-visibility-section.tsx @@ -6,7 +6,7 @@ export const ToggleVisibilitySection: FC<{ element: string property: string }> = async ({ element, property }) => { - const { result } = + const rawJs = await compileMdx(`### Toggle Visibility [#toggle-visibility-for-${property}] You can toggle visibility of the ${element} on the specific pages by setting \`theme.${property}\` property in the \`_meta.js\` file: @@ -20,5 +20,5 @@ export default { } } \`\`\``) - return + return } diff --git a/examples/docs/src/content/features/mdx.mdx b/examples/docs/src/content/features/mdx.mdx index 8d4ca74acf..e1e48cebab 100644 --- a/examples/docs/src/content/features/mdx.mdx +++ b/examples/docs/src/content/features/mdx.mdx @@ -22,14 +22,14 @@ export async function Demo() { MDX document to a syntax tree and then generates a JSX document from that tree. ` - const { result } = await compileMdx(`~~~mdx filename="example.mdx" + const rawJs = await compileMdx(`~~~mdx filename="example.mdx" ${mdx} ~~~ Generates: ${mdx}`) - return + return } diff --git a/examples/swr-site/app/[lang]/remote/graphql-eslint/[[...slug]]/page.tsx b/examples/swr-site/app/[lang]/remote/graphql-eslint/[[...slug]]/page.tsx index d15febdbb6..1f9a054add 100644 --- a/examples/swr-site/app/[lang]/remote/graphql-eslint/[[...slug]]/page.tsx +++ b/examples/swr-site/app/[lang]/remote/graphql-eslint/[[...slug]]/page.tsx @@ -33,8 +33,8 @@ export default async function Page(props) { `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${docsPath}${filePath}` ) const data = await response.text() - const { result } = await compileMdx(data, { filePath }) - const { default: MDXContent, useTOC, metadata, title } = evaluate(result) + const rawJs = await compileMdx(data, { filePath }) + const { default: MDXContent, useTOC, metadata, title } = evaluate(rawJs) return ( diff --git a/examples/swr-site/app/[lang]/remote/graphql-yoga/[[...slug]]/page.tsx b/examples/swr-site/app/[lang]/remote/graphql-yoga/[[...slug]]/page.tsx index f2d206daad..841fcadb25 100644 --- a/examples/swr-site/app/[lang]/remote/graphql-yoga/[[...slug]]/page.tsx +++ b/examples/swr-site/app/[lang]/remote/graphql-yoga/[[...slug]]/page.tsx @@ -35,9 +35,9 @@ export default async function Page(props) { `https://raw.githubusercontent.com/${user}/${repo}/${branch}/${docsPath}${filePath}` ) const data = await response.text() - const { result } = await compileMdx(data, { filePath }) + const rawJs = await compileMdx(data, { filePath }) - const { default: MDXContent, useTOC, metadata, title } = evaluate(result) + const { default: MDXContent, useTOC, metadata, title } = evaluate(rawJs) return ( diff --git a/packages/nextra/__test__/compile.test.ts b/packages/nextra/__test__/compile.test.ts index 0ef4d2f507..5e9f47d086 100644 --- a/packages/nextra/__test__/compile.test.ts +++ b/packages/nextra/__test__/compile.test.ts @@ -8,7 +8,7 @@ const mdxOptions = { describe('Compile', () => { it('should work with export default', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( `import foo from './foo' ## heading @@ -16,7 +16,7 @@ describe('Compile', () => { export default foo`, { mdxOptions } ) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = '' @@ -36,13 +36,13 @@ export default foo`, `) }) it('should work with export as default', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( `## heading export { foo as default } from './foo'`, { mdxOptions } ) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = '' @@ -64,19 +64,19 @@ export { foo as default } from './foo'`, describe('Process heading', () => { it('code-h1', async () => { - const { result } = await compileMdx('# `codegen.yml`', { mdxOptions }) - expect(clean(result)).resolves.toMatchSnapshot() + const rawJs = await compileMdx('# `codegen.yml`', { mdxOptions }) + expect(clean(rawJs)).resolves.toMatchSnapshot() }) it('code-with-text-h1', async () => { - const { result } = await compileMdx('# `codegen.yml` file', { mdxOptions }) - expect(clean(result)).resolves.toMatchSnapshot() + const rawJs = await compileMdx('# `codegen.yml` file', { mdxOptions }) + expect(clean(rawJs)).resolves.toMatchSnapshot() }) it('static-h1', async () => { - const { result } = await compileMdx('# Hello World', { mdxOptions }) - expect(clean(result)).resolves.toMatchSnapshot() + const rawJs = await compileMdx('# Hello World', { mdxOptions }) + expect(clean(rawJs)).resolves.toMatchSnapshot() }) it('dynamic-h1', async () => { - const res = await compileMdx( + const rawJs = await compileMdx( ` import { useRouter } from 'next/router' @@ -89,15 +89,14 @@ export const TagName = () => { `, { mdxOptions } ) - res.result = await clean(res.result) - expect(res).toMatchSnapshot() + expect(await clean(rawJs)).toMatchSnapshot() }) it('no-h1', async () => { - const { result } = await compileMdx('## H2', { mdxOptions }) - expect(clean(result)).resolves.toMatchSnapshot() + const rawJs = await compileMdx('## H2', { mdxOptions }) + expect(clean(rawJs)).resolves.toMatchSnapshot() }) it('use custom heading id', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( ` # My Header [#test-id] ## Some extra space [#extra-space]  @@ -108,7 +107,7 @@ export const TagName = () => { ###### bar Qux [#]`, { mdxOptions } ) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = 'My Header' @@ -182,8 +181,8 @@ export const TagName = () => { `) }) it('use github-slugger', async () => { - const { result } = await compileMdx('### My Header', { mdxOptions }) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + const rawJs = await compileMdx('### My Header', { mdxOptions }) + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = '' @@ -210,7 +209,7 @@ export const TagName = () => { }) it('should merge headings from partial components', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( ` import FromMdx from './one.mdx' import FromMarkdown from './two.md' @@ -243,7 +242,7 @@ import Last from './three.mdx' `, { mdxOptions, latex: true } ) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = '' @@ -379,7 +378,7 @@ import Last from './three.mdx' `) }) it('should not attach headings with parent Tab or Tabs.Tab', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( ` ## foo @@ -392,56 +391,56 @@ import Last from './three.mdx' `, { mdxOptions } ) - expect(result).toMatch(`export function useTOC(props) { + expect(rawJs).toMatch(`export function useTOC(props) { return []; }`) - expect(result).not.toMatch('id=') + expect(rawJs).not.toMatch('id=') }) }) describe('Link', () => { it('supports .md links', async () => { - const { result } = await compileMdx('[link](../file.md)', { mdxOptions }) - expect(result).toMatch('<_components.a href="../file">') + const rawJs = await compileMdx('[link](../file.md)', { mdxOptions }) + expect(rawJs).toMatch('<_components.a href="../file">') }) it('supports .mdx links', async () => { - const { result } = await compileMdx('[link](../file.mdx)', { mdxOptions }) - expect(result).toMatch('<_components.a href="../file">') + const rawJs = await compileMdx('[link](../file.mdx)', { mdxOptions }) + expect(rawJs).toMatch('<_components.a href="../file">') }) it('supports URL links', async () => { - const { result } = await compileMdx('[link](../file)', { mdxOptions }) - expect(result).toMatch('<_components.a href="../file">') + const rawJs = await compileMdx('[link](../file)', { mdxOptions }) + expect(rawJs).toMatch('<_components.a href="../file">') }) it('supports query', async () => { - const { result } = await compileMdx('[link](../file.md?query=a)', { + const rawJs = await compileMdx('[link](../file.md?query=a)', { mdxOptions }) - expect(result).toMatch('<_components.a href="../file?query=a">') + expect(rawJs).toMatch('<_components.a href="../file?query=a">') }) it('supports anchor', async () => { - const { result } = await compileMdx('[link](../file.md#anchor)', { + const rawJs = await compileMdx('[link](../file.md#anchor)', { mdxOptions }) - expect(result).toMatch('<_components.a href="../file#anchor">') + expect(rawJs).toMatch('<_components.a href="../file#anchor">') }) it('supports external .md links', async () => { - const { result } = await compileMdx('[link](https://example.com/file.md)', { + const rawJs = await compileMdx('[link](https://example.com/file.md)', { mdxOptions }) - expect(result).toMatch('<_components.a href="https://example.com/file.md">') + expect(rawJs).toMatch('<_components.a href="https://example.com/file.md">') }) it('supports external .mdx links', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( '[link](https://example.com/file.mdx)', { mdxOptions } ) - expect(result).toMatch( + expect(rawJs).toMatch( '<_components.a href="https://example.com/file.mdx">' ) }) @@ -450,44 +449,44 @@ describe('Link', () => { describe('Code block', () => { describe('Filename', () => { it('attach with "codeHighlight: true" by default', async () => { - const { result } = await compileMdx('```text filename="test.js"\n```', { + const rawJs = await compileMdx('```text filename="test.js"\n```', { mdxOptions, search: true }) - expect(result).toMatch( + expect(rawJs).toMatch( '<_components.pre tabIndex="0" data-language="text" data-word-wrap="" data-filename="test.js">' ) }) it('attach with "codeHighlight: false"', async () => { - const { result } = await compileMdx('```js filename="test.js"\n```', { + const rawJs = await compileMdx('```js filename="test.js"\n```', { mdxOptions, codeHighlight: false }) - expect(result).toMatch( + expect(rawJs).toMatch( '<_components.pre data-filename="test.js" data-word-wrap="">' ) }) it('not highlight filename as substring', async () => { - const { result } = await compileMdx('```js filename="/foo/"\nfoo\n```', { + const rawJs = await compileMdx('```js filename="/foo/"\nfoo\n```', { mdxOptions, codeHighlight: true // processed only by rehype-pretty-code }) - expect(result).not.toMatch( + expect(rawJs).not.toMatch( 'className="highlighted">{"foo"}' ) - expect(result).toMatch('}}>{"foo"}') + expect(rawJs).toMatch('}}>{"foo"}') }) }) describe('Highlight', () => { it('should support line highlights', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( '```js filename="test.js" {1}\n123\n```', { mdxOptions } ) - expect(result).toMatch('<_components.span data-highlighted-line="">') + expect(rawJs).toMatch('<_components.span data-highlighted-line="">') }) }) @@ -495,31 +494,31 @@ describe('Code block', () => { for (const codeHighlight of [true, false]) { describe(`codeHighlight: ${codeHighlight}`, () => { it('attach with "copy"', async () => { - const { result } = await compileMdx('```js copy\n```', { + const rawJs = await compileMdx('```js copy\n```', { mdxOptions, codeHighlight, search: true }) - expect(result).toMatch('data-word-wrap="" data-copy="">') + expect(rawJs).toMatch('data-word-wrap="" data-copy="">') }) it('attach with "defaultShowCopyCode: true"', async () => { - const { result } = await compileMdx('```js\n```', { + const rawJs = await compileMdx('```js\n```', { mdxOptions, defaultShowCopyCode: true, codeHighlight, search: true }) - expect(result).toMatch('data-word-wrap="" data-copy="">') + expect(rawJs).toMatch('data-word-wrap="" data-copy="">') }) it('not attach with "defaultShowCopyCode: true" and "copy=false"', async () => { - const { result } = await compileMdx('```js copy=false\n```', { + const rawJs = await compileMdx('```js copy=false\n```', { mdxOptions, defaultShowCopyCode: true, codeHighlight }) - expect(result).not.toMatch('data-copy=""') + expect(rawJs).not.toMatch('data-copy=""') }) }) } diff --git a/packages/nextra/__test__/latex.test.ts b/packages/nextra/__test__/latex.test.ts index e5869e83cc..f59bb5bae3 100644 --- a/packages/nextra/__test__/latex.test.ts +++ b/packages/nextra/__test__/latex.test.ts @@ -9,8 +9,8 @@ const options = { describe('LaTeX', () => { describe('KaTeX', () => { it('should convert ```math code block language', async () => { - const { result } = await compileMdx('```math\nx^2\n```', options) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + const rawJs = await compileMdx('```math\nx^2\n```', options) + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ 'use strict' @@ -114,8 +114,8 @@ describe('LaTeX', () => { const MATH_LANG = '```math\nx^2\n```' it('should convert math inline', async () => { - const { result } = await compileMdx(INLINE_MATH, options) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + const rawJs = await compileMdx(INLINE_MATH, options) + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = '' @@ -144,8 +144,8 @@ describe('LaTeX', () => { }) it('should convert ```math code block language', async () => { - const { result } = await compileMdx(MATH_LANG, options) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + const rawJs = await compileMdx(MATH_LANG, options) + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = '' @@ -175,8 +175,8 @@ import foo from 'foo' export let bar ${MATH_LANG}` - const { result } = await compileMdx(rawMdx, options) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + const rawJs = await compileMdx(rawMdx, options) + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = '' diff --git a/packages/nextra/src/client/components/playground.tsx b/packages/nextra/src/client/components/playground.tsx index ad252890d3..16e9284352 100644 --- a/packages/nextra/src/client/components/playground.tsx +++ b/packages/nextra/src/client/components/playground.tsx @@ -30,8 +30,8 @@ export const Playground: FC< // Importing in useEffect to not increase global bundle size const { compileMdx } = await import('../../server/compile.js') try { - const mdx = await compileMdx(source) - setCompiledSource(mdx.result) + const rawJs = await compileMdx(source) + setCompiledSource(rawJs) setError(null) } catch (error) { setError(error) diff --git a/packages/nextra/src/server/loader.ts b/packages/nextra/src/server/loader.ts index 6f9e4cf603..ae8eb65eb3 100644 --- a/packages/nextra/src/server/loader.ts +++ b/packages/nextra/src/server/loader.ts @@ -115,7 +115,7 @@ export async function loader( const rawJs = await compileMetadata(source, { filePath }) return rawJs } - const { result } = await compileMdx(source, { + const compiledSource = await compileMdx(source, { mdxOptions: { ...mdxOptions, jsx: true, @@ -150,11 +150,11 @@ export async function loader( // Imported as a normal component, no need to add the layout. if (!isPageImport) { - return `${result} + return `${compiledSource} export default MDXLayout` } const rawJs = `import { HOC_MDXWrapper } from 'nextra/setup-page' -${result} +${compiledSource} export default HOC_MDXWrapper( MDXLayout, {metadata, title, toc:useTOC()} diff --git a/packages/nextra/src/server/page-map/index-page.ts b/packages/nextra/src/server/page-map/index-page.ts index f88c9a29dd..99c8c72fb6 100644 --- a/packages/nextra/src/server/page-map/index-page.ts +++ b/packages/nextra/src/server/page-map/index-page.ts @@ -33,9 +33,9 @@ export async function createIndexPage(pageMap: PageMapItem[]): Promise { if (hasCards) { result.push('') } - const rawJsx = result.join('\n') + const rawMdx = result.join('\n') - const mdx = await compileMdx(rawJsx) + const rawJs = await compileMdx(rawMdx) - return mdx.result + return rawJs } diff --git a/packages/nextra/src/server/rehype-plugins/rehype-extract-toc-content.test.ts b/packages/nextra/src/server/rehype-plugins/rehype-extract-toc-content.test.ts index 4a28e5e97e..8e76e9ee3e 100644 --- a/packages/nextra/src/server/rehype-plugins/rehype-extract-toc-content.test.ts +++ b/packages/nextra/src/server/rehype-plugins/rehype-extract-toc-content.test.ts @@ -11,7 +11,7 @@ const opts = { describe('rehypeExtractTocContent', () => { it('should work with footnotes or user ids', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( ` ## foo bar[^1] @@ -20,7 +20,7 @@ bar[^1] `, opts ) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = '' @@ -98,7 +98,7 @@ bar[^1] }) it('should fill heading deeply', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( ` import { Steps } from 'nextra/components' @@ -112,7 +112,7 @@ import { Steps } from 'nextra/components' `, opts ) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = '' @@ -156,7 +156,7 @@ import { Steps } from 'nextra/components' }) it('should extract', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( ` # Heading 1 @@ -184,7 +184,7 @@ export const metadata = { `, opts ) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = 'Heading 1' @@ -336,11 +336,11 @@ import { MDXRemote } from 'nextra/mdx-remote' ` - const { result } = await compileMdx(rawMdx, { + const rawJs = await compileMdx(rawMdx, { ...opts, filePath: '[[...slug]].mdx' }) - const res = await clean(result) + const res = await clean(rawJs) expect(res).toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ @@ -395,10 +395,8 @@ export const myVar = 123 ### 123 {myVar}` - const { result } = await compileMdx(rawMdx) - const res = await clean(result) - - expect(res).toMatchInlineSnapshot(` + const rawJs = await compileMdx(rawMdx) + expect(await clean(rawJs)).toMatchInlineSnapshot(` "'use strict' const { Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs } = arguments[0] const title = '' diff --git a/packages/nextra/src/server/remark-plugins/__tests__/remark-mdx-title.test.ts b/packages/nextra/src/server/remark-plugins/__tests__/remark-mdx-title.test.ts index 57630f9ca3..0c8ac1d1ce 100644 --- a/packages/nextra/src/server/remark-plugins/__tests__/remark-mdx-title.test.ts +++ b/packages/nextra/src/server/remark-plugins/__tests__/remark-mdx-title.test.ts @@ -14,7 +14,7 @@ describe('remarkMdxTitle', () => { describe('should prioritize frontmatter', () => { it('yaml', async () => { const title = 'From yaml frontMatter' - const { result } = await compileMdx( + const rawJs = await compileMdx( `--- title: ${title} --- @@ -22,40 +22,40 @@ title: ${title} # Hello`, opts ) - expect(clean(result)).resolves.toMatch(`const title = '${title}'`) + expect(clean(rawJs)).resolves.toMatch(`const title = '${title}'`) }) it('esm', async () => { const title = 'From esm frontMatter' - const { result } = await compileMdx( + const rawJs = await compileMdx( `export const metadata = { title: '${title}' } # Hello`, opts ) - expect(clean(result)).resolves.toMatch(`const title = '${title}'`) + expect(clean(rawJs)).resolves.toMatch(`const title = '${title}'`) }) }) it('should fallback to first h1', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( `## h2 # h1 1 # h1 2 `, opts ) - expect(clean(result)).resolves.toMatch("const title = 'h1 1'") + expect(clean(rawJs)).resolves.toMatch("const title = 'h1 1'") }) it('should fallback to capitalized filename', async () => { - const { result } = await compileMdx('', opts) - expect(clean(result)).resolves.toMatch("const title = 'My Test File'") + const rawJs = await compileMdx('', opts) + expect(clean(rawJs)).resolves.toMatch("const title = 'My Test File'") }) it('should set metadata.title if missing', async () => { - const { result } = await compileMdx('# should attach', opts) - expect(clean(result)).resolves.toMatch(`export const metadata = { + const rawJs = await compileMdx('# should attach', opts) + expect(clean(rawJs)).resolves.toMatch(`export const metadata = { title: 'should attach' }`) }) diff --git a/packages/nextra/src/server/remark-plugins/__tests__/remark-remove-imports.test.ts b/packages/nextra/src/server/remark-plugins/__tests__/remark-remove-imports.test.ts index cb9ee54c91..5a88b3ea60 100644 --- a/packages/nextra/src/server/remark-plugins/__tests__/remark-remove-imports.test.ts +++ b/packages/nextra/src/server/remark-plugins/__tests__/remark-remove-imports.test.ts @@ -7,7 +7,7 @@ const opts = { describe('remarkRemoveImports', () => { it('should fill heading deeply', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( ` import { Steps } from 'nextra/components' @@ -19,7 +19,7 @@ export const Test = ({value}) => value `, opts ) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ 'use strict' diff --git a/packages/nextra/src/server/remark-plugins/__tests__/remark-static-images.test.ts b/packages/nextra/src/server/remark-plugins/__tests__/remark-static-images.test.ts index 1395c0ec91..d28320a9f5 100644 --- a/packages/nextra/src/server/remark-plugins/__tests__/remark-static-images.test.ts +++ b/packages/nextra/src/server/remark-plugins/__tests__/remark-static-images.test.ts @@ -3,7 +3,7 @@ import { compileMdx } from '../../compile.js' describe('remarkStaticImages', () => { it('should insert same import only once', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( ` ![](../foo.png) @@ -19,7 +19,7 @@ describe('remarkStaticImages', () => { } ) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ import __img0 from '../foo.png' @@ -56,7 +56,7 @@ describe('remarkStaticImages', () => { }) it('should work with link definitions', async () => { - const { result } = await compileMdx( + const rawJs = await compileMdx( ` ![One][link-def] @@ -79,7 +79,7 @@ describe('remarkStaticImages', () => { } ) - expect(clean(result)).resolves.toMatchInlineSnapshot(` + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ import __img0 from '../foo.png' diff --git a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts index 112d991645..dae205e802 100644 --- a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts +++ b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts @@ -48,7 +48,9 @@ export const remarkMdxFrontMatter: Plugin<[], Root> = )! const frontMatter = getFrontMatterASTObject(frontMatterNode) - file.data.frontMatter = estreeToValue(frontMatter) + if (estreeToValue(frontMatter).mdxOptions) { + throw new Error('`frontMatter.mdxOptions` is no longer supported') + } } function traverseArray( From 62e124005eef2d47dac55b100adefa0ee321a4c6 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 12:21:53 +0300 Subject: [PATCH 23/40] moree --- packages/nextra/__test__/compile.test.ts | 18 +++++++----------- .../remark-plugins/remark-mdx-frontmatter.ts | 2 +- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/nextra/__test__/compile.test.ts b/packages/nextra/__test__/compile.test.ts index 5e9f47d086..3f8eb9fc87 100644 --- a/packages/nextra/__test__/compile.test.ts +++ b/packages/nextra/__test__/compile.test.ts @@ -436,13 +436,10 @@ describe('Link', () => { }) it('supports external .mdx links', async () => { - const rawJs = await compileMdx( - '[link](https://example.com/file.mdx)', - { mdxOptions } - ) - expect(rawJs).toMatch( - '<_components.a href="https://example.com/file.mdx">' - ) + const rawJs = await compileMdx('[link](https://example.com/file.mdx)', { + mdxOptions + }) + expect(rawJs).toMatch('<_components.a href="https://example.com/file.mdx">') }) }) @@ -482,10 +479,9 @@ describe('Code block', () => { describe('Highlight', () => { it('should support line highlights', async () => { - const rawJs = await compileMdx( - '```js filename="test.js" {1}\n123\n```', - { mdxOptions } - ) + const rawJs = await compileMdx('```js filename="test.js" {1}\n123\n```', { + mdxOptions + }) expect(rawJs).toMatch('<_components.span data-highlighted-line="">') }) }) diff --git a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts index dae205e802..c5f02f8ada 100644 --- a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts +++ b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts @@ -5,7 +5,7 @@ import type { Parent, Root } from 'mdast' import type { Plugin } from 'unified' import { parse as parseYaml } from 'yaml' import { createAstExportConst } from '../utils.js' -import { isExportNode, getFrontMatterASTObject } from './remark-mdx-title.js' +import { getFrontMatterASTObject, isExportNode } from './remark-mdx-title.js' function createNode(data: Record) { return { From 31e41ca761698a425eb3e2881f21d9b40b31f4c3 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 12:22:56 +0300 Subject: [PATCH 24/40] moree --- packages/nextra/src/server/compile.ts | 36 ++++----------------------- 1 file changed, 5 insertions(+), 31 deletions(-) diff --git a/packages/nextra/src/server/compile.ts b/packages/nextra/src/server/compile.ts index f027b5e9c6..d8be9b5bc2 100644 --- a/packages/nextra/src/server/compile.ts +++ b/packages/nextra/src/server/compile.ts @@ -83,11 +83,7 @@ export async function compileMdx( whiteListTagsStyling = [], lastCommitTime }: Partial = {} -): Promise<{ - result: string - title?: string - frontMatter: FrontMatter -}> { +): Promise { const { jsx = false, format: _format = 'mdx', @@ -124,32 +120,10 @@ export async function compileMdx( try { const vFile = await processor.process(fileCompatible) - - const data = vFile.data as { - title?: string - frontMatter: FrontMatter - } - - const { title, frontMatter } = data - // https://github.com/shuding/nextra/issues/1032 - const result = String(vFile).replaceAll('__esModule', '_\\_esModule') - - if (typeof title !== 'string') { - logger.error('`title` is not defined') - } - if (!frontMatter) { - logger.error('`frontMatter` is not defined') - } - - if (frontMatter.mdxOptions) { - throw new Error('`frontMatter.mdxOptions` is no longer supported') - } - - return { - result, - title, - frontMatter - } + const rawJs = String(vFile) + // https://github.com/shuding/nextra/issues/1032 + .replaceAll('__esModule', '_\\_esModule') + return rawJs } catch (error) { console.error(`[nextra] Error compiling ${filePath}.`) throw error From 6b0f1f8a412ef0e25d50577b2910107451c369ba Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 12:27:41 +0300 Subject: [PATCH 25/40] moree --- packages/nextra/src/server/compile.ts | 3 +- packages/nextra/src/server/loader.ts | 2 +- packages/nextra/src/server/page-map/get.ts | 2 +- .../nextra/src/server/page-map/index-page.ts | 4 +- .../remark-assign-frontmatter.ts | 4 +- .../remark-plugins/remark-mdx-frontmatter.ts | 55 +++++++++---------- 6 files changed, 34 insertions(+), 36 deletions(-) diff --git a/packages/nextra/src/server/compile.ts b/packages/nextra/src/server/compile.ts index d8be9b5bc2..16d3a48e6e 100644 --- a/packages/nextra/src/server/compile.ts +++ b/packages/nextra/src/server/compile.ts @@ -13,7 +13,7 @@ import remarkMath from 'remark-math' import remarkReadingTime from 'remark-reading-time' import remarkSmartypants from 'remark-smartypants' import type { Pluggable, Plugin } from 'unified' -import type { FrontMatter, LoaderOptions, ReadingTime } from '../types.js' +import type { LoaderOptions } from '../types.js' import { CWD, MARKDOWN_URL_EXTENSION_RE } from './constants.js' import { recmaRewriteFunctionBody, @@ -38,7 +38,6 @@ import { remarkRemoveImports, remarkStaticImage } from './remark-plugins/index.js' -import { logger } from './utils.js' type Processor = ReturnType diff --git a/packages/nextra/src/server/loader.ts b/packages/nextra/src/server/loader.ts index ae8eb65eb3..fcf80f8134 100644 --- a/packages/nextra/src/server/loader.ts +++ b/packages/nextra/src/server/loader.ts @@ -3,7 +3,7 @@ import { transformerTwoslash } from '@shikijs/twoslash' import { findPagesDir } from 'next/dist/lib/find-pages-dir.js' import slash from 'slash' import type { LoaderContext } from 'webpack' -import type { LoaderOptions, PageOpts } from '../types.js' +import type { LoaderOptions } from '../types.js' import { compileMetadata } from './compile-metadata.js' import { compileMdx } from './compile.js' import { diff --git a/packages/nextra/src/server/page-map/get.ts b/packages/nextra/src/server/page-map/get.ts index 88f50fb875..d76372cd48 100644 --- a/packages/nextra/src/server/page-map/get.ts +++ b/packages/nextra/src/server/page-map/get.ts @@ -1,4 +1,4 @@ -import { Folder, PageMapItem } from '../../types' +import type { Folder, PageMapItem } from '../../types.js' function importPageMap(lang = ''): Promise<{ pageMap: PageMapItem[] diff --git a/packages/nextra/src/server/page-map/index-page.ts b/packages/nextra/src/server/page-map/index-page.ts index 99c8c72fb6..5f994e16b4 100644 --- a/packages/nextra/src/server/page-map/index-page.ts +++ b/packages/nextra/src/server/page-map/index-page.ts @@ -1,4 +1,4 @@ -import { MdxFile, PageMapItem } from '../../types' +import type { MdxFile, PageMapItem } from '../../types.js' import { compileMdx } from '../compile.js' function renderCard(item: MdxFile): string { @@ -8,7 +8,7 @@ function renderCard(item: MdxFile): string { } export async function createIndexPage(pageMap: PageMapItem[]): Promise { - let result = [] + const result = [] let hasCards = false for (const item of pageMap) { if ('data' in item) { diff --git a/packages/nextra/src/server/remark-plugins/remark-assign-frontmatter.ts b/packages/nextra/src/server/remark-plugins/remark-assign-frontmatter.ts index 8da2b0c77f..0c99d4216c 100644 --- a/packages/nextra/src/server/remark-plugins/remark-assign-frontmatter.ts +++ b/packages/nextra/src/server/remark-plugins/remark-assign-frontmatter.ts @@ -1,10 +1,10 @@ import path from 'node:path' -import { Property } from 'estree' +import type { Property } from 'estree' import { valueToEstree } from 'estree-util-value-to-estree' import type { Root } from 'mdast' import slash from 'slash' import type { Plugin } from 'unified' -import { ReadingTime } from '../../types.js' +import type { ReadingTime } from '../../types.js' import { CWD } from '../constants.js' import { getFrontMatterASTObject, isExportNode } from './remark-mdx-title.js' diff --git a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts index c5f02f8ada..b5918fc3ab 100644 --- a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts +++ b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts @@ -18,40 +18,39 @@ function createNode(data: Record) { } as MdxjsEsm } -export const remarkMdxFrontMatter: Plugin<[], Root> = - () => (ast: Parent, file) => { - const yamlNodeIndex = ast.children.findIndex(node => node.type === 'yaml') - const esmNodeIndex = ast.children.findIndex((node: any) => - isExportNode(node, 'metadata') - ) - const hasYaml = yamlNodeIndex !== -1 - const hasEsm = esmNodeIndex !== -1 +export const remarkMdxFrontMatter: Plugin<[], Root> = () => (ast: Parent) => { + const yamlNodeIndex = ast.children.findIndex(node => node.type === 'yaml') + const esmNodeIndex = ast.children.findIndex((node: any) => + isExportNode(node, 'metadata') + ) + const hasYaml = yamlNodeIndex !== -1 + const hasEsm = esmNodeIndex !== -1 - if (hasYaml) { - if (hasEsm) { - throw new Error( - "Both yaml frontMatter and esm export frontMatter aren't supported. Keep only 1." - ) - } + if (hasYaml) { + if (hasEsm) { + throw new Error( + "Both yaml frontMatter and esm export frontMatter aren't supported. Keep only 1." + ) + } - const raw = (ast.children[yamlNodeIndex] as { value: string }).value - const data = parseYaml(raw) + const raw = (ast.children[yamlNodeIndex] as { value: string }).value + const data = parseYaml(raw) - ast.children[yamlNodeIndex] = createNode(data) - } else if (!hasEsm) { - // Attach dummy node - ast.children.unshift(createNode({})) - } + ast.children[yamlNodeIndex] = createNode(data) + } else if (!hasEsm) { + // Attach dummy node + ast.children.unshift(createNode({})) + } - const frontMatterNode = ast.children.find((node: any) => - isExportNode(node, 'metadata') - )! - const frontMatter = getFrontMatterASTObject(frontMatterNode) + const frontMatterNode = ast.children.find((node: any) => + isExportNode(node, 'metadata') + )! + const frontMatter = getFrontMatterASTObject(frontMatterNode) - if (estreeToValue(frontMatter).mdxOptions) { - throw new Error('`frontMatter.mdxOptions` is no longer supported') - } + if (estreeToValue(frontMatter).mdxOptions) { + throw new Error('`frontMatter.mdxOptions` is no longer supported') } +} function traverseArray( nodes: ArrayExpression['elements'], From d31b5c7daa0414f0a0dcc25c21e9a5bf3f5b2a54 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Mon, 11 Nov 2024 12:36:08 +0300 Subject: [PATCH 26/40] moree --- packages/nextra/src/server/compile.ts | 2 +- packages/nextra/src/server/constants.ts | 9 +++++++++ packages/nextra/src/server/index.ts | 13 +++---------- packages/nextra/src/server/loader.ts | 16 +++++++--------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/nextra/src/server/compile.ts b/packages/nextra/src/server/compile.ts index 16d3a48e6e..bfe664e6fd 100644 --- a/packages/nextra/src/server/compile.ts +++ b/packages/nextra/src/server/compile.ts @@ -119,7 +119,7 @@ export async function compileMdx( try { const vFile = await processor.process(fileCompatible) - const rawJs = String(vFile) + const rawJs = (vFile.value as string) // https://github.com/shuding/nextra/issues/1032 .replaceAll('__esModule', '_\\_esModule') return rawJs diff --git a/packages/nextra/src/server/constants.ts b/packages/nextra/src/server/constants.ts index 9ab1ab918c..4a07e161b5 100644 --- a/packages/nextra/src/server/constants.ts +++ b/packages/nextra/src/server/constants.ts @@ -2,6 +2,7 @@ * Benefit of server/constants - do not include unneeded `path` polyfill in client bundle, * while importing constants in client file */ +import { sep } from 'node:path' import type { Property } from 'estree' export const MARKDOWN_EXTENSION_RE = /\.mdx?$/ @@ -26,9 +27,17 @@ export const DEFAULT_PROPERTY_PROPS = { export const TOC_HEADING_RE = /^h[2-6]$/ +const SEP = sep === '/' ? '/' : '\\\\' + export const GET_PAGE_MAP_PATH = '/nextra/dist/server/page-map/get.js' +export const GET_PAGE_MAP_RE = new RegExp( + GET_PAGE_MAP_PATH.replaceAll('/', SEP).replaceAll('.', '\\.') +) export const PAGE_MAP_PLACEHOLDER_PATH = '/nextra/dist/server/page-map/placeholder.js' +export const PAGE_MAP_PLACEHOLDER_RE = new RegExp( + PAGE_MAP_PLACEHOLDER_PATH.replaceAll('/', SEP).replaceAll('.', '\\.') +) export const METADATA_ONLY_RQ = '?metadata' diff --git a/packages/nextra/src/server/index.ts b/packages/nextra/src/server/index.ts index 75ae98b567..810a0f1447 100644 --- a/packages/nextra/src/server/index.ts +++ b/packages/nextra/src/server/index.ts @@ -7,8 +7,10 @@ import { fromZodError } from 'zod-validation-error' import type { Nextra } from '../types.js' import { GET_PAGE_MAP_PATH, + GET_PAGE_MAP_RE, MARKDOWN_EXTENSION_RE, - PAGE_MAP_PLACEHOLDER_PATH + PAGE_MAP_PLACEHOLDER_PATH, + PAGE_MAP_PLACEHOLDER_RE } from './constants.js' import { nextraConfigSchema } from './schemas.js' import { logger } from './utils.js' @@ -23,15 +25,6 @@ const DIRNAME = path.dirname(FILENAME) const LOADER_PATH = path.join(DIRNAME, '..', '..', 'loader.cjs') -const SEP = path.sep === '/' ? '/' : '\\\\' - -const PAGE_MAP_PLACEHOLDER_RE = new RegExp( - PAGE_MAP_PLACEHOLDER_PATH.replaceAll('/', SEP).replaceAll('.', '\\.') -) -const GET_PAGE_MAP_RE = new RegExp( - GET_PAGE_MAP_PATH.replaceAll('/', SEP).replaceAll('.', '\\.') -) - export function getContentDirectory() { // Next.js gives priority to `app` over `src/app`, we do the same for `content` directory const [contentDir] = fg.sync(['{src/,}content'], { onlyDirectories: true }) diff --git a/packages/nextra/src/server/loader.ts b/packages/nextra/src/server/loader.ts index fcf80f8134..07bd6d82fa 100644 --- a/packages/nextra/src/server/loader.ts +++ b/packages/nextra/src/server/loader.ts @@ -1,17 +1,16 @@ import path from 'node:path' import { transformerTwoslash } from '@shikijs/twoslash' import { findPagesDir } from 'next/dist/lib/find-pages-dir.js' -import slash from 'slash' import type { LoaderContext } from 'webpack' import type { LoaderOptions } from '../types.js' import { compileMetadata } from './compile-metadata.js' import { compileMdx } from './compile.js' import { CWD, - GET_PAGE_MAP_PATH, + GET_PAGE_MAP_RE, IS_PRODUCTION, METADATA_ONLY_RQ, - PAGE_MAP_PLACEHOLDER_PATH + PAGE_MAP_PLACEHOLDER_RE } from './constants.js' import { getContentDirectory } from './index.js' import { findMetaAndPageFilePaths } from './page-map/find-meta-and-page-file-paths.js' @@ -75,9 +74,8 @@ export async function loader( whiteListTagsStyling } = this.getOptions() const { resourcePath, resourceQuery } = this - const filePath = slash(resourcePath) - if (filePath.includes(PAGE_MAP_PLACEHOLDER_PATH)) { + if (PAGE_MAP_PLACEHOLDER_RE.test(resourcePath)) { const locale = resourceQuery.replace('?lang=', '') if (!IS_PRODUCTION) { // Add `app` and `content` folders as the dependencies, so Webpack will @@ -102,7 +100,7 @@ export async function loader( const rawJs = await convertPageMapToJs({ pageMap, mdxPages }) return rawJs } - if (filePath.includes(GET_PAGE_MAP_PATH)) { + if (GET_PAGE_MAP_RE.test(resourcePath)) { const rawJs = replaceDynamicResourceQuery( source, 'import(`./placeholder.js?lang=${lang}`)', @@ -112,7 +110,7 @@ export async function loader( } if (!IS_PRODUCTION && resourceQuery === METADATA_ONLY_RQ) { - const rawJs = await compileMetadata(source, { filePath }) + const rawJs = await compileMetadata(source, { filePath: resourcePath }) return rawJs } const compiledSource = await compileMdx(source, { @@ -139,13 +137,13 @@ export async function loader( search, latex, codeHighlight, - filePath, + filePath: resourcePath, useCachedCompiler: true, isPageImport, whiteListTagsStyling, // Run only on production because it can slow down Fast Refresh for uncommitted files // https://github.com/shuding/nextra/issues/3675#issuecomment-2466416366 - lastCommitTime: IS_PRODUCTION ? await getLastCommitTime(filePath) : NOW + lastCommitTime: IS_PRODUCTION ? await getLastCommitTime(resourcePath) : NOW }) // Imported as a normal component, no need to add the layout. From 7e17c933ffb9c2b8d4f8b6350036bba79eba9620 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 20:25:43 +0700 Subject: [PATCH 27/40] moree --- packages/nextra/__test__/compile.test.ts | 2 +- .../rehype-extract-toc-content.test.ts | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/nextra/__test__/compile.test.ts b/packages/nextra/__test__/compile.test.ts index 3f8eb9fc87..d35db66bc3 100644 --- a/packages/nextra/__test__/compile.test.ts +++ b/packages/nextra/__test__/compile.test.ts @@ -89,7 +89,7 @@ export const TagName = () => { `, { mdxOptions } ) - expect(await clean(rawJs)).toMatchSnapshot() + expect(clean(rawJs)).resolves.toMatchSnapshot() }) it('no-h1', async () => { const rawJs = await compileMdx('## H2', { mdxOptions }) diff --git a/packages/nextra/src/server/rehype-plugins/rehype-extract-toc-content.test.ts b/packages/nextra/src/server/rehype-plugins/rehype-extract-toc-content.test.ts index 8e76e9ee3e..338c248acc 100644 --- a/packages/nextra/src/server/rehype-plugins/rehype-extract-toc-content.test.ts +++ b/packages/nextra/src/server/rehype-plugins/rehype-extract-toc-content.test.ts @@ -340,9 +340,7 @@ import { MDXRemote } from 'nextra/mdx-remote' ...opts, filePath: '[[...slug]].mdx' }) - const res = await clean(rawJs) - - expect(res).toMatchInlineSnapshot(` + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = '[[...slug]]' @@ -396,7 +394,7 @@ export const myVar = 123 ### 123 {myVar}` const rawJs = await compileMdx(rawMdx) - expect(await clean(rawJs)).toMatchInlineSnapshot(` + expect(clean(rawJs)).resolves.toMatchInlineSnapshot(` "'use strict' const { Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs } = arguments[0] const title = '' @@ -461,10 +459,10 @@ export const myVar = 123 } " `) - expect(res).toMatch('default: _createMdxContent') - expect(res).toMatch('const metadata = {') - expect(res).toMatch('function useTOC') - expect(res).not.toMatch('MDXContent') + expect(rawJs).toMatch('default: _createMdxContent') + expect(rawJs).toMatch('const metadata = {') + expect(rawJs).toMatch('function useTOC') + expect(rawJs).not.toMatch('MDXContent') }) }) }) From 5873059b6087d16b1b109da5509efdab185f7163 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 20:35:24 +0700 Subject: [PATCH 28/40] more --- packages/nextra/src/server/constants.ts | 16 --------------- packages/nextra/src/server/index.ts | 21 +++++++++++++------- packages/nextra/src/server/loader.ts | 8 +++----- packages/nextra/src/server/page-map/to-js.ts | 8 +++----- 4 files changed, 20 insertions(+), 33 deletions(-) diff --git a/packages/nextra/src/server/constants.ts b/packages/nextra/src/server/constants.ts index 4a07e161b5..dbca5498e8 100644 --- a/packages/nextra/src/server/constants.ts +++ b/packages/nextra/src/server/constants.ts @@ -2,7 +2,6 @@ * Benefit of server/constants - do not include unneeded `path` polyfill in client bundle, * while importing constants in client file */ -import { sep } from 'node:path' import type { Property } from 'estree' export const MARKDOWN_EXTENSION_RE = /\.mdx?$/ @@ -13,8 +12,6 @@ export const MARKDOWN_URL_EXTENSION_RE = /\.mdx?(?:(?=[#?])|$)/ export const IS_PRODUCTION = process.env.NODE_ENV === 'production' -export const META_RE = /_meta\.[jt]sx?$/ - export const EXTERNAL_URL_RE = /^https?:\/\// export const DEFAULT_PROPERTY_PROPS = { @@ -27,17 +24,4 @@ export const DEFAULT_PROPERTY_PROPS = { export const TOC_HEADING_RE = /^h[2-6]$/ -const SEP = sep === '/' ? '/' : '\\\\' - -export const GET_PAGE_MAP_PATH = '/nextra/dist/server/page-map/get.js' -export const GET_PAGE_MAP_RE = new RegExp( - GET_PAGE_MAP_PATH.replaceAll('/', SEP).replaceAll('.', '\\.') -) - -export const PAGE_MAP_PLACEHOLDER_PATH = - '/nextra/dist/server/page-map/placeholder.js' -export const PAGE_MAP_PLACEHOLDER_RE = new RegExp( - PAGE_MAP_PLACEHOLDER_PATH.replaceAll('/', SEP).replaceAll('.', '\\.') -) - export const METADATA_ONLY_RQ = '?metadata' diff --git a/packages/nextra/src/server/index.ts b/packages/nextra/src/server/index.ts index 810a0f1447..fbc7648c53 100644 --- a/packages/nextra/src/server/index.ts +++ b/packages/nextra/src/server/index.ts @@ -5,13 +5,7 @@ import fg from 'fast-glob' import type { RuleSetRule } from 'webpack' import { fromZodError } from 'zod-validation-error' import type { Nextra } from '../types.js' -import { - GET_PAGE_MAP_PATH, - GET_PAGE_MAP_RE, - MARKDOWN_EXTENSION_RE, - PAGE_MAP_PLACEHOLDER_PATH, - PAGE_MAP_PLACEHOLDER_RE -} from './constants.js' +import { MARKDOWN_EXTENSION_RE } from './constants.js' import { nextraConfigSchema } from './schemas.js' import { logger } from './utils.js' @@ -25,6 +19,19 @@ const DIRNAME = path.dirname(FILENAME) const LOADER_PATH = path.join(DIRNAME, '..', '..', 'loader.cjs') +const SEP = path.sep === '/' ? '/' : '\\\\' + +const GET_PAGE_MAP_PATH = '/nextra/dist/server/page-map/get.js' + +const PAGE_MAP_PLACEHOLDER_PATH = '/nextra/dist/server/page-map/placeholder.js' + +export const GET_PAGE_MAP_RE = new RegExp( + GET_PAGE_MAP_PATH.replaceAll('/', SEP).replaceAll('.', '\\.') +) +export const PAGE_MAP_PLACEHOLDER_RE = new RegExp( + PAGE_MAP_PLACEHOLDER_PATH.replaceAll('/', SEP).replaceAll('.', '\\.') +) + export function getContentDirectory() { // Next.js gives priority to `app` over `src/app`, we do the same for `content` directory const [contentDir] = fg.sync(['{src/,}content'], { onlyDirectories: true }) diff --git a/packages/nextra/src/server/loader.ts b/packages/nextra/src/server/loader.ts index 07bd6d82fa..17184e43d6 100644 --- a/packages/nextra/src/server/loader.ts +++ b/packages/nextra/src/server/loader.ts @@ -5,14 +5,12 @@ import type { LoaderContext } from 'webpack' import type { LoaderOptions } from '../types.js' import { compileMetadata } from './compile-metadata.js' import { compileMdx } from './compile.js' +import { CWD, IS_PRODUCTION, METADATA_ONLY_RQ } from './constants.js' import { - CWD, GET_PAGE_MAP_RE, - IS_PRODUCTION, - METADATA_ONLY_RQ, + getContentDirectory, PAGE_MAP_PLACEHOLDER_RE -} from './constants.js' -import { getContentDirectory } from './index.js' +} from './index.js' import { findMetaAndPageFilePaths } from './page-map/find-meta-and-page-file-paths.js' import { convertPageMapToJs } from './page-map/to-js.js' import { convertToPageMap } from './page-map/to-page-map.js' diff --git a/packages/nextra/src/server/page-map/to-js.ts b/packages/nextra/src/server/page-map/to-js.ts index 28a6b0ba9d..ae462bf67a 100644 --- a/packages/nextra/src/server/page-map/to-js.ts +++ b/packages/nextra/src/server/page-map/to-js.ts @@ -1,13 +1,11 @@ import type { ImportDeclaration } from 'estree' import { toJs } from 'estree-util-to-js' import type { Import, TItem } from '../../types.js' -import { - MARKDOWN_EXTENSION_RE, - META_RE, - METADATA_ONLY_RQ -} from '../constants.js' +import { MARKDOWN_EXTENSION_RE, METADATA_ONLY_RQ } from '../constants.js' import { convertPageMapToAst } from './to-ast.js' +const META_RE = /_meta\.[jt]sx?$/ + export async function convertPageMapToJs({ pageMap, mdxPages From e8a8efafa9eab80f7a4de80ba8cb8372fe7ecae6 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 20:40:35 +0700 Subject: [PATCH 29/40] more --- .../src/server/remark-plugins/remark-mdx-frontmatter.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts index b5918fc3ab..7d6d3632c4 100644 --- a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts +++ b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts @@ -18,7 +18,7 @@ function createNode(data: Record) { } as MdxjsEsm } -export const remarkMdxFrontMatter: Plugin<[], Root> = () => (ast: Parent) => { +export const remarkMdxFrontMatter: Plugin<[], Root> = () => (ast, file) => { const yamlNodeIndex = ast.children.findIndex(node => node.type === 'yaml') const esmNodeIndex = ast.children.findIndex((node: any) => isExportNode(node, 'metadata') @@ -46,10 +46,13 @@ export const remarkMdxFrontMatter: Plugin<[], Root> = () => (ast: Parent) => { isExportNode(node, 'metadata') )! const frontMatter = getFrontMatterASTObject(frontMatterNode) - - if (estreeToValue(frontMatter).mdxOptions) { + const frontMatterValue = estreeToValue(frontMatter) + if (frontMatterValue.mdxOptions) { throw new Error('`frontMatter.mdxOptions` is no longer supported') } + if (process.env.NODE_ENV === 'test') { + file.data.frontMatter = frontMatterValue + } } function traverseArray( From cfea09093755f902070b062333bfbe87c8b2c67b Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 20:41:26 +0700 Subject: [PATCH 30/40] more --- packages/nextra/__test__/to-page-map.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/nextra/__test__/to-page-map.test.ts b/packages/nextra/__test__/to-page-map.test.ts index a2114f0a5d..f12d94c25e 100644 --- a/packages/nextra/__test__/to-page-map.test.ts +++ b/packages/nextra/__test__/to-page-map.test.ts @@ -121,6 +121,7 @@ describe('generatePageMap()', () => { "app/docs/docs-theme/built-ins/layout/page.mdx", "app/docs/docs-theme/built-ins/navbar/page.mdx", "app/docs/docs-theme/built-ins/not-found/page.mdx", + "app/docs/docs-theme/built-ins/page.mdx", "app/docs/docs-theme/page-configuration/page.mdx", "app/docs/docs-theme/page.mdx", "app/docs/docs-theme/start/page.mdx", @@ -314,6 +315,11 @@ describe('generatePageMap()', () => { "name": "not-found", "route": "/docs/docs-theme/built-ins/not-found", }, + { + "__pagePath": "app/docs/docs-theme/built-ins/page.mdx", + "name": "index", + "route": "/docs/docs-theme/built-ins", + }, ], "name": "built-ins", "route": "/docs/docs-theme/built-ins", From 564f014734c077f7c18c797c745b9bd4ab641c32 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 20:52:10 +0700 Subject: [PATCH 31/40] more --- .../nextra/__test__/__snapshots__/compile.test.ts.snap | 8 ++------ .../rehype-extract-toc-content.test.ts | 4 +++- .../__tests__/remark-mdx-frontmatter.test.ts | 4 ++-- .../__tests__/remark-mdx-title.test.ts | 8 ++++---- .../__tests__/remark-remove-imports.test.ts | 4 ++-- .../__tests__/remark-static-images.test.ts | 4 ++-- .../src/server/remark-plugins/remark-mdx-frontmatter.ts | 2 +- 7 files changed, 16 insertions(+), 18 deletions(-) rename packages/nextra/src/server/{rehype-plugins => __tests__}/rehype-extract-toc-content.test.ts (99%) rename packages/nextra/src/server/{remark-plugins => }/__tests__/remark-mdx-frontmatter.test.ts (95%) rename packages/nextra/src/server/{remark-plugins => }/__tests__/remark-mdx-title.test.ts (88%) rename packages/nextra/src/server/{remark-plugins => }/__tests__/remark-remove-imports.test.ts (92%) rename packages/nextra/src/server/{remark-plugins => }/__tests__/remark-static-images.test.ts (96%) diff --git a/packages/nextra/__test__/__snapshots__/compile.test.ts.snap b/packages/nextra/__test__/__snapshots__/compile.test.ts.snap index 4041fca870..3ebc3a0c74 100644 --- a/packages/nextra/__test__/__snapshots__/compile.test.ts.snap +++ b/packages/nextra/__test__/__snapshots__/compile.test.ts.snap @@ -52,9 +52,7 @@ function MDXLayout(props) { `; exports[`Process heading > dynamic-h1 1`] = ` -{ - "frontMatter": {}, - "result": "/*@jsxRuntime automatic*/ +"/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = 'Posts Tagged with ""' export const metadata = { @@ -81,9 +79,7 @@ function MDXLayout(props) { ) } -", - "title": "Posts Tagged with """, -} +" `; exports[`Process heading > no-h1 1`] = ` diff --git a/packages/nextra/src/server/rehype-plugins/rehype-extract-toc-content.test.ts b/packages/nextra/src/server/__tests__/rehype-extract-toc-content.test.ts similarity index 99% rename from packages/nextra/src/server/rehype-plugins/rehype-extract-toc-content.test.ts rename to packages/nextra/src/server/__tests__/rehype-extract-toc-content.test.ts index 338c248acc..8f98396f69 100644 --- a/packages/nextra/src/server/rehype-plugins/rehype-extract-toc-content.test.ts +++ b/packages/nextra/src/server/__tests__/rehype-extract-toc-content.test.ts @@ -344,7 +344,9 @@ import { MDXRemote } from 'nextra/mdx-remote' "/*@jsxRuntime automatic*/ /*@jsxImportSource react*/ export const title = '[[...slug]]' - export const metadata = {} + export const metadata = { + filePath: '[[...slug]].mdx' + } import { MDXRemote } from 'nextra/mdx-remote' export function useTOC(props) { return [ diff --git a/packages/nextra/src/server/remark-plugins/__tests__/remark-mdx-frontmatter.test.ts b/packages/nextra/src/server/__tests__/remark-mdx-frontmatter.test.ts similarity index 95% rename from packages/nextra/src/server/remark-plugins/__tests__/remark-mdx-frontmatter.test.ts rename to packages/nextra/src/server/__tests__/remark-mdx-frontmatter.test.ts index 543dba80ac..cf2de63071 100644 --- a/packages/nextra/src/server/remark-plugins/__tests__/remark-mdx-frontmatter.test.ts +++ b/packages/nextra/src/server/__tests__/remark-mdx-frontmatter.test.ts @@ -1,7 +1,7 @@ import { compile } from '@mdx-js/mdx' import remarkFrontmatter from 'remark-frontmatter' -import { clean } from '../../../../__test__/test-utils.js' -import { remarkMdxFrontMatter } from '../remark-mdx-frontmatter.js' +import { clean } from '../../../__test__/test-utils.js' +import { remarkMdxFrontMatter } from '../remark-plugins/remark-mdx-frontmatter.js' function process(content: string) { return compile(content, { diff --git a/packages/nextra/src/server/remark-plugins/__tests__/remark-mdx-title.test.ts b/packages/nextra/src/server/__tests__/remark-mdx-title.test.ts similarity index 88% rename from packages/nextra/src/server/remark-plugins/__tests__/remark-mdx-title.test.ts rename to packages/nextra/src/server/__tests__/remark-mdx-title.test.ts index 0c8ac1d1ce..d1f7d7b708 100644 --- a/packages/nextra/src/server/remark-plugins/__tests__/remark-mdx-title.test.ts +++ b/packages/nextra/src/server/__tests__/remark-mdx-title.test.ts @@ -1,9 +1,8 @@ -import { describe } from 'vitest' -import { clean } from '../../../../__test__/test-utils.js' -import { compileMdx } from '../../compile.js' +import { clean } from '../../../__test__/test-utils.js' +import { compileMdx } from '../compile.js' const opts = { - filePath: '/foo/my-test-file.mdx', + filePath: 'foo/my-test-file.mdx', mdxOptions: { outputFormat: 'program', jsx: true @@ -56,6 +55,7 @@ title: ${title} it('should set metadata.title if missing', async () => { const rawJs = await compileMdx('# should attach', opts) expect(clean(rawJs)).resolves.toMatch(`export const metadata = { + filePath: 'foo/my-test-file.mdx', title: 'should attach' }`) }) diff --git a/packages/nextra/src/server/remark-plugins/__tests__/remark-remove-imports.test.ts b/packages/nextra/src/server/__tests__/remark-remove-imports.test.ts similarity index 92% rename from packages/nextra/src/server/remark-plugins/__tests__/remark-remove-imports.test.ts rename to packages/nextra/src/server/__tests__/remark-remove-imports.test.ts index 5a88b3ea60..51fcbe95f9 100644 --- a/packages/nextra/src/server/remark-plugins/__tests__/remark-remove-imports.test.ts +++ b/packages/nextra/src/server/__tests__/remark-remove-imports.test.ts @@ -1,5 +1,5 @@ -import { clean } from '../../../../__test__/test-utils.js' -import { compileMdx } from '../../compile.js' +import { clean } from '../../../__test__/test-utils.js' +import { compileMdx } from '../compile.js' const opts = { mdxOptions: { jsx: true } diff --git a/packages/nextra/src/server/remark-plugins/__tests__/remark-static-images.test.ts b/packages/nextra/src/server/__tests__/remark-static-images.test.ts similarity index 96% rename from packages/nextra/src/server/remark-plugins/__tests__/remark-static-images.test.ts rename to packages/nextra/src/server/__tests__/remark-static-images.test.ts index d28320a9f5..c277a7bdfc 100644 --- a/packages/nextra/src/server/remark-plugins/__tests__/remark-static-images.test.ts +++ b/packages/nextra/src/server/__tests__/remark-static-images.test.ts @@ -1,5 +1,5 @@ -import { clean } from '../../../../__test__/test-utils.js' -import { compileMdx } from '../../compile.js' +import { clean } from '../../../__test__/test-utils.js' +import { compileMdx } from '../compile.js' describe('remarkStaticImages', () => { it('should insert same import only once', async () => { diff --git a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts index 7d6d3632c4..ddcbfd57c7 100644 --- a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts +++ b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts @@ -1,7 +1,7 @@ import type { ArrayExpression, ObjectExpression } from 'estree' import { valueToEstree } from 'estree-util-value-to-estree' import type { MdxjsEsm } from 'hast-util-to-estree/lib/handlers/mdxjs-esm' -import type { Parent, Root } from 'mdast' +import type { Root } from 'mdast' import type { Plugin } from 'unified' import { parse as parseYaml } from 'yaml' import { createAstExportConst } from '../utils.js' From 260b9fe4303eee5621c90c093fdf0b9dddc4c31d Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 20:55:52 +0700 Subject: [PATCH 32/40] more --- .changeset/chilled-turkeys-smell.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changeset/chilled-turkeys-smell.md diff --git a/.changeset/chilled-turkeys-smell.md b/.changeset/chilled-turkeys-smell.md new file mode 100644 index 0000000000..4016a0bba4 --- /dev/null +++ b/.changeset/chilled-turkeys-smell.md @@ -0,0 +1,7 @@ +--- +'nextra-theme-blog': major +'nextra-theme-docs': major +'nextra': major +--- + +make `compileMdx` from `nextra/compile` return a `string` instead of an `object` From e33c218882300957a03f0516cedb39976e7ec37f Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 21:13:59 +0700 Subject: [PATCH 33/40] [skip ci] --- .../server/__tests__/remark-mdx-title.test.ts | 1 + .../remark-plugins/remark-mdx-frontmatter.ts | 63 ++++++++++--------- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/packages/nextra/src/server/__tests__/remark-mdx-title.test.ts b/packages/nextra/src/server/__tests__/remark-mdx-title.test.ts index d1f7d7b708..036d14ee29 100644 --- a/packages/nextra/src/server/__tests__/remark-mdx-title.test.ts +++ b/packages/nextra/src/server/__tests__/remark-mdx-title.test.ts @@ -1,3 +1,4 @@ +import { describe } from 'vitest' import { clean } from '../../../__test__/test-utils.js' import { compileMdx } from '../compile.js' diff --git a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts index ddcbfd57c7..7bca50d85e 100644 --- a/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts +++ b/packages/nextra/src/server/remark-plugins/remark-mdx-frontmatter.ts @@ -18,42 +18,43 @@ function createNode(data: Record) { } as MdxjsEsm } -export const remarkMdxFrontMatter: Plugin<[], Root> = () => (ast, file) => { - const yamlNodeIndex = ast.children.findIndex(node => node.type === 'yaml') - const esmNodeIndex = ast.children.findIndex((node: any) => - isExportNode(node, 'metadata') - ) - const hasYaml = yamlNodeIndex !== -1 - const hasEsm = esmNodeIndex !== -1 +export const remarkMdxFrontMatter: Plugin<[], Root> = + () => (ast: Root, file) => { + const yamlNodeIndex = ast.children.findIndex(node => node.type === 'yaml') + const esmNodeIndex = ast.children.findIndex((node: any) => + isExportNode(node, 'metadata') + ) + const hasYaml = yamlNodeIndex !== -1 + const hasEsm = esmNodeIndex !== -1 - if (hasYaml) { - if (hasEsm) { - throw new Error( - "Both yaml frontMatter and esm export frontMatter aren't supported. Keep only 1." - ) - } + if (hasYaml) { + if (hasEsm) { + throw new Error( + "Both yaml frontMatter and esm export frontMatter aren't supported. Keep only 1." + ) + } - const raw = (ast.children[yamlNodeIndex] as { value: string }).value - const data = parseYaml(raw) + const raw = (ast.children[yamlNodeIndex] as { value: string }).value + const data = parseYaml(raw) - ast.children[yamlNodeIndex] = createNode(data) - } else if (!hasEsm) { - // Attach dummy node - ast.children.unshift(createNode({})) - } + ast.children[yamlNodeIndex] = createNode(data) + } else if (!hasEsm) { + // Attach dummy node + ast.children.unshift(createNode({})) + } - const frontMatterNode = ast.children.find((node: any) => - isExportNode(node, 'metadata') - )! - const frontMatter = getFrontMatterASTObject(frontMatterNode) - const frontMatterValue = estreeToValue(frontMatter) - if (frontMatterValue.mdxOptions) { - throw new Error('`frontMatter.mdxOptions` is no longer supported') - } - if (process.env.NODE_ENV === 'test') { - file.data.frontMatter = frontMatterValue + const frontMatterNode = ast.children.find((node: any) => + isExportNode(node, 'metadata') + )! + const frontMatter = getFrontMatterASTObject(frontMatterNode) + const frontMatterValue = estreeToValue(frontMatter) + if (frontMatterValue.mdxOptions) { + throw new Error('`frontMatter.mdxOptions` is no longer supported') + } + if (process.env.NODE_ENV === 'test') { + file.data.frontMatter = frontMatterValue + } } -} function traverseArray( nodes: ArrayExpression['elements'], From afd73d20c3cc99f4bc8e8f2c5821238b581fbba7 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 21:29:40 +0700 Subject: [PATCH 34/40] more --- docs/app/docs/blog-theme/start/page.mdx | 21 --------------------- docs/app/docs/custom-theme/page.mdx | 2 +- docs/app/docs/docs-theme/start/page.mdx | 21 --------------------- docs/components/install-nextra-theme.mdx | 21 +++++++++++++++++++++ 4 files changed, 22 insertions(+), 43 deletions(-) diff --git a/docs/app/docs/blog-theme/start/page.mdx b/docs/app/docs/blog-theme/start/page.mdx index ab6d11a2da..62a3ccd6c6 100644 --- a/docs/app/docs/blog-theme/start/page.mdx +++ b/docs/app/docs/blog-theme/start/page.mdx @@ -36,27 +36,6 @@ npm i next react react-dom nextra nextra-theme-blog -### Add Next.js Config - -Create the following `next.config.mjs` file in your project's root directory: - -```js filename="next.config.mjs" -import nextra from 'nextra' - -const withNextra = nextra({ - // ... Other Nextra config options -}) - -// If you have other Next.js configurations, you can pass them as the parameter: -export default withNextra({ - // ... Other Next.js config options -}) -``` - -With the above configuration, Nextra can handle Markdown files in your Next.js -project, with the specified theme. Other Nextra configurations can be found in -[Guide](/docs/guide). - ### Create Blog Theme Config Lastly, create the corresponding `theme.config.jsx` file in your project's root diff --git a/docs/app/docs/custom-theme/page.mdx b/docs/app/docs/custom-theme/page.mdx index 6f855a8318..5558f86c16 100644 --- a/docs/app/docs/custom-theme/page.mdx +++ b/docs/app/docs/custom-theme/page.mdx @@ -28,7 +28,7 @@ const withNextra = nextra({ theme: './theme.tsx' }) -// If you have other Next.js configurations, you can pass them as the parameter: +// You can include other Next.js configuration options here, in addition to Nextra settings: export default withNextra({ // ... Other Next.js config options }) diff --git a/docs/app/docs/docs-theme/start/page.mdx b/docs/app/docs/docs-theme/start/page.mdx index 82adaade33..42f6a58bf2 100644 --- a/docs/app/docs/docs-theme/start/page.mdx +++ b/docs/app/docs/docs-theme/start/page.mdx @@ -54,27 +54,6 @@ npm i next react react-dom nextra nextra-theme-docs -### Add Next.js Config - -Create the following `next.config.mjs` file in your project's root directory: - -```js filename="next.config.mjs" -import nextra from 'nextra' - -const withNextra = nextra({ - // ... Other Nextra config options -}) - -// If you have other Next.js configurations, you can pass them as the parameter: -export default withNextra({ - // ... Other Next.js config options -}) -``` - -With the above configuration, Nextra can handle Markdown files in your Next.js -project, with the specified theme. Other Nextra configurations can be found in -[Guide](/docs/guide). - ### Add `mdx-components.js` in root directory ```ts filename="mdx-components.js" diff --git a/docs/components/install-nextra-theme.mdx b/docs/components/install-nextra-theme.mdx index 989450cfd3..02ba472512 100644 --- a/docs/components/install-nextra-theme.mdx +++ b/docs/components/install-nextra-theme.mdx @@ -30,3 +30,24 @@ npm run start > > If you're not familiar with Next.js, note that development mode is > significantly slower since Next.js compiles every page you navigate to. + +### Add Next.js Config + +Create the following `next.config.mjs` file in your project's root directory: + +```js filename="next.config.mjs" +import nextra from 'nextra' + +const withNextra = nextra({ + // ... Other Nextra config options +}) + +// You can include other Next.js configuration options here, in addition to Nextra settings: +export default withNextra({ + // ... Other Next.js config options +}) +``` + +With the above configuration, Nextra can handle Markdown files in your Next.js +project, with the specified theme. Other Nextra configurations can be found in +[Guide](/docs/guide). From f45e6119c60a0cdfedc496b52be4c5a108b11322 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 21:36:11 +0700 Subject: [PATCH 35/40] more --- docs/components/install-nextra-theme.mdx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/components/install-nextra-theme.mdx b/docs/components/install-nextra-theme.mdx index 02ba472512..a58a534024 100644 --- a/docs/components/install-nextra-theme.mdx +++ b/docs/components/install-nextra-theme.mdx @@ -1,4 +1,4 @@ -Add the following scripts in `package.json`: +Add the following scripts to your `package.json`: ```json filename="package.json" "scripts": { @@ -10,7 +10,13 @@ Add the following scripts in `package.json`: > [!TIP] > -> You can use Turbopack by appending `--turbopack` flag in `dev` command +> You can enable Turbopack in development by appending the `--turbopack` flag to +> the `dev` command: +> +> ```diff filename="package.json" +> - "dev": "next", +> + "dev": "next --turbopack", +> ``` You can start the server in development mode with the following command according to your package manager: @@ -33,7 +39,8 @@ npm run start ### Add Next.js Config -Create the following `next.config.mjs` file in your project's root directory: +Create a `next.config.mjs` file in your project's root directory with the +following content: ```js filename="next.config.mjs" import nextra from 'nextra' @@ -48,6 +55,6 @@ export default withNextra({ }) ``` -With the above configuration, Nextra can handle Markdown files in your Next.js -project, with the specified theme. Other Nextra configurations can be found in +With this configuration, Nextra will handle Markdown files in your Next.js +project. For more Nextra configuration options, check out the [Guide](/docs/guide). From 80db90ab973b30ca9dbb2e8ce680a54391289832 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 21:41:34 +0700 Subject: [PATCH 36/40] more --- docs/app/docs/guide/custom-css/page.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/app/docs/guide/custom-css/page.mdx b/docs/app/docs/guide/custom-css/page.mdx index 3ba40da2ea..1976c82ef6 100644 --- a/docs/app/docs/guide/custom-css/page.mdx +++ b/docs/app/docs/guide/custom-css/page.mdx @@ -22,15 +22,15 @@ body { } ``` -Import your CSS files in root layout: +To apply your global styles, import your CSS file in the root layout file: ```jsx filename="app/layout.jsx" import '../path/to/your/styles.css' export default async function RootLayout({ children }) { - // ... + // ... Your layout logic here } ``` -To learn more about CSS support in Next.js, check out the -[Next.js documentation](https://nextjs.org/docs/basic-features/built-in-css-support). +For more information on how to use CSS in Next.js, check out the +[Next.js CSS Support documentation](https://nextjs.org/docs/basic-features/built-in-css-support). From d3176c17fa33bcceebfa875c08ae41773e10a0e7 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 21:45:44 +0700 Subject: [PATCH 37/40] more --- .../docs/advanced/customize-the-cascade-layers/page.mdx | 8 ++------ docs/app/docs/advanced/tailwind-css/page.mdx | 8 ++++---- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/app/docs/advanced/customize-the-cascade-layers/page.mdx b/docs/app/docs/advanced/customize-the-cascade-layers/page.mdx index 4b8942e2a4..2f2aba5612 100644 --- a/docs/app/docs/advanced/customize-the-cascade-layers/page.mdx +++ b/docs/app/docs/advanced/customize-the-cascade-layers/page.mdx @@ -50,12 +50,8 @@ Import your CSS file at the top-level layout of your application (e.g. ```jsx filename="app/layout.jsx" import '../path/to/your/styles.css' -export default function RootLayout({ children }) { - return ( - - {children} - - ) +export default async function RootLayout({ children }) { + // ... Your layout logic here } ``` diff --git a/docs/app/docs/advanced/tailwind-css/page.mdx b/docs/app/docs/advanced/tailwind-css/page.mdx index 9b88a640f2..9a046f842d 100644 --- a/docs/app/docs/advanced/tailwind-css/page.mdx +++ b/docs/app/docs/advanced/tailwind-css/page.mdx @@ -37,9 +37,9 @@ export default { > [!TIP] > -> You can use `tailwind.config.ts` as well. +> You can also use a `tailwind.config.ts` file if you prefer TypeScript for your Tailwind CSS configuration. -## Create `globals.css` file +## Create the `globals.css` File Create a CSS file for Tailwind directives, `globals.css` for example: @@ -55,13 +55,13 @@ Create a CSS file for Tailwind directives, `globals.css` for example: > `nextra-theme-docs` or `nextra-theme-blog` because they already imports > Tailwind CSS preflight styles in their `style.css` files. -## Import styles in root layout +## Import styles in the root layout ```jsx filename="app/layout.jsx" import '../path/to/your/globals.css' export default async function RootLayout({ children }) { - // ... + // ... Your layout logic here } ``` From 9df3e09c38e234a35979c2c7913e8e8f1dca55d3 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 21:48:07 +0700 Subject: [PATCH 38/40] more --- docs/app/docs/advanced/tailwind-css/page.mdx | 21 +++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/app/docs/advanced/tailwind-css/page.mdx b/docs/app/docs/advanced/tailwind-css/page.mdx index 9a046f842d..b5d4e167b9 100644 --- a/docs/app/docs/advanced/tailwind-css/page.mdx +++ b/docs/app/docs/advanced/tailwind-css/page.mdx @@ -37,25 +37,28 @@ export default { > [!TIP] > -> You can also use a `tailwind.config.ts` file if you prefer TypeScript for your Tailwind CSS configuration. +> You can also use a `tailwind.config.ts` file if you prefer TypeScript for your +> Tailwind CSS configuration. -## Create the `globals.css` File +## Create the `globals.css` file Create a CSS file for Tailwind directives, `globals.css` for example: ```css filename="globals.css" -@tailwind base; /* preflight styles */ -@tailwind components; -@tailwind utilities; +@tailwind base; /* Apply Tailwind's base styles (Preflight) */ +@tailwind components; /* Include component styles */ +@tailwind utilities; /* Include utility classes */ ``` > [!NOTE] > -> You don't need to have `@tailwind base` directive while using -> `nextra-theme-docs` or `nextra-theme-blog` because they already imports -> Tailwind CSS preflight styles in their `style.css` files. +> If you're using `nextra-theme-docs` or `nextra-theme-blog`, you don't need to +> include the `@tailwind base` directive. These themes already import Tailwind's +> preflight styles in their `style.css` files. -## Import styles in the root layout +## Import styles in the Root Layout + +To apply the styles globally, import the `globals.css` file in your root layout file: ```jsx filename="app/layout.jsx" import '../path/to/your/globals.css' From aec8b707471968ca6d18f29d6cf8627995834672 Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 21:51:30 +0700 Subject: [PATCH 39/40] more --- docs/app/docs/advanced/tailwind-css/page.mdx | 3 ++- docs/app/docs/docs-theme/start/page.mdx | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/app/docs/advanced/tailwind-css/page.mdx b/docs/app/docs/advanced/tailwind-css/page.mdx index b5d4e167b9..22f5690e80 100644 --- a/docs/app/docs/advanced/tailwind-css/page.mdx +++ b/docs/app/docs/advanced/tailwind-css/page.mdx @@ -58,7 +58,8 @@ Create a CSS file for Tailwind directives, `globals.css` for example: ## Import styles in the Root Layout -To apply the styles globally, import the `globals.css` file in your root layout file: +To apply the styles globally, import the `globals.css` file in your root layout +file: ```jsx filename="app/layout.jsx" import '../path/to/your/globals.css' diff --git a/docs/app/docs/docs-theme/start/page.mdx b/docs/app/docs/docs-theme/start/page.mdx index 42f6a58bf2..98e20f751b 100644 --- a/docs/app/docs/docs-theme/start/page.mdx +++ b/docs/app/docs/docs-theme/start/page.mdx @@ -9,11 +9,11 @@ import { Steps } from 'nextra/components' # Docs Theme -Nextra docs theme is a theme that includes almost everything you need to build a +Nextra Docs Theme is a theme that includes almost everything you need to build a modern documentation website. It includes a top navigation bar, a search bar, a pages sidebar, a Table of Contents (TOC), and other built-in components. -This website itself is built with the Nextra docs theme. +This website itself is built with the Nextra Docs Theme. ## Quick Start from Template @@ -25,7 +25,7 @@ clicking the link: [![](https://vercel.com/button)](https://vercel.com/new/clone?s=https%3A%2F%2Fgithub.com%2Fshuding%2Fnextra-docs-template&showOptionalTeamCreation=false) Vercel will fork the -[Nextra docs template](https://github.com/shuding/nextra-docs-template) and +[Nextra Docs template](https://github.com/shuding/nextra-docs-template) and deploy the site for you. Once done, every commit in the repository will be deployed automatically. @@ -39,8 +39,8 @@ You can also manually fork the ### Install -To create a Nextra docs site manually, you have to install **Next.js**, -**React**, **Nextra**, and **Nextra docs theme**. In your project directory, run +To create a Nextra Docs site manually, you have to install **Next.js**, +**React**, **Nextra**, and **Nextra Docs Theme**. In your project directory, run the following command to install the dependencies: ```sh npm2yarn @@ -77,7 +77,7 @@ export function useMDXComponents(components) { ### Create Root Layout Lastly, create the root layout of your application in `app` folder. This will be -used to configure the Nextra docs theme: +used to configure the Nextra Docs Theme: ```jsx filename="app/layout.jsx" import { Footer, Layout, Navbar } from 'nextra-theme-docs' From 91e77ccfe97d42652d97985a64addedb77b1693e Mon Sep 17 00:00:00 2001 From: Dimitri POSTOLOV Date: Tue, 12 Nov 2024 21:59:20 +0700 Subject: [PATCH 40/40] more --- docs/app/docs/docs-theme/start/page.mdx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/app/docs/docs-theme/start/page.mdx b/docs/app/docs/docs-theme/start/page.mdx index 98e20f751b..5e4bf6eb39 100644 --- a/docs/app/docs/docs-theme/start/page.mdx +++ b/docs/app/docs/docs-theme/start/page.mdx @@ -54,13 +54,15 @@ npm i next react react-dom nextra nextra-theme-docs -### Add `mdx-components.js` in root directory +### Add `mdx-components.js` in the root directory ```ts filename="mdx-components.js" import { useMDXComponents as getDocsMDXComponents } from 'nextra-theme-docs' +// Get the default MDX components from Nextra Docs theme const docsComponents = getDocsMDXComponents() +// Merge custom components with default Nextra components export function useMDXComponents(components) { return { ...docsComponents, @@ -71,13 +73,13 @@ export function useMDXComponents(components) { > [!TIP] > -> You can use `.jsx`, `.ts` and `.tsx` extensions for your `mdx-components` file -> as well. +> You can use `.jsx`, `.ts`, or `.tsx` extensions for your `mdx-components` +> file. -### Create Root Layout +### Create the Root Layout -Lastly, create the root layout of your application in `app` folder. This will be -used to configure the Nextra Docs Theme: +Next, create the root layout of your application inside the `app` folder. This +layout will be used to configure the Nextra Docs Theme: ```jsx filename="app/layout.jsx" import { Footer, Layout, Navbar } from 'nextra-theme-docs' @@ -86,8 +88,8 @@ import { getPageMap } from 'nextra/page-map' import 'nextra-theme-docs/style.css' export const metadata = { - // ... Your metadata API - // https://nextjs.org/docs/app/building-your-application/optimizing/metadata + // Define your metadata here + // For more information on metadata API, see: https://nextjs.org/docs/app/building-your-application/optimizing/metadata } const banner = Nextra 4.0 is released 🎉