diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 0000000..f03f5a2
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["biomejs.biome", "unifiedjs.vscode-mdx"]
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 368e090..3f8c462 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,8 +1,44 @@
{
"editor.codeActionsOnSave": {
+ "quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit",
- "quickfix.biome": "explicit"
+ "source.formatDocument.biome": "explicit"
},
+ "editor.defaultFormatter": "biomejs.biome",
+ "editor.formatOnSave": true,
"eslint.enable": false,
- "prettier.enable": false
+ "prettier.enable": false,
+ "[typescriptreact]": {
+ "editor.defaultFormatter": "biomejs.biome"
+ },
+ "[typescript]": {
+ "editor.defaultFormatter": "biomejs.biome"
+ },
+ "[javascript]": {
+ "editor.defaultFormatter": "biomejs.biome"
+ },
+ "[javascriptreact]": {
+ "editor.defaultFormatter": "biomejs.biome"
+ },
+ "[json]": {
+ "editor.defaultFormatter": "biomejs.biome"
+ },
+ "[jsonc]": {
+ "editor.defaultFormatter": "biomejs.biome"
+ },
+ "[cjs]": {
+ "editor.defaultFormatter": "biomejs.biome"
+ },
+ "[mjs]": {
+ "editor.defaultFormatter": "biomejs.biome"
+ },
+ "[cts]": {
+ "editor.defaultFormatter": "biomejs.biome"
+ },
+ "[mts]": {
+ "editor.defaultFormatter": "biomejs.biome"
+ },
+ "[css]": {
+ "editor.defaultFormatter": "biomejs.biome"
+ }
}
diff --git a/lefthook.yml b/lefthook.yml
index dce7bb7..1718374 100644
--- a/lefthook.yml
+++ b/lefthook.yml
@@ -1,6 +1,6 @@
pre-commit:
commands:
check:
- glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}"
+ glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc,css}"
run: npx @biomejs/biome check --write --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {staged_files}
stage_fixed: true
\ No newline at end of file
diff --git a/next.config.ts b/next.config.ts
index 87e4159..0e0416f 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -9,6 +9,10 @@ const withNextra = nextra({
export default withNextra({
reactStrictMode: true,
+ i18n: {
+ locales: ['en', 'zh'],
+ defaultLocale: 'en',
+ },
// https://github.com/vercel/turborepo/issues/4832#issuecomment-1751407444
webpack(config) {
config.module.rules.push({
diff --git a/public/demo.png b/public/demo.png
deleted file mode 100644
index 3751514..0000000
Binary files a/public/demo.png and /dev/null differ
diff --git a/src/app/[[...mdxPath]]/page.tsx b/src/app/[lang]/[[...mdxPath]]/page.tsx
similarity index 61%
rename from src/app/[[...mdxPath]]/page.tsx
rename to src/app/[lang]/[[...mdxPath]]/page.tsx
index 4b4c412..4c50b6a 100644
--- a/src/app/[[...mdxPath]]/page.tsx
+++ b/src/app/[lang]/[[...mdxPath]]/page.tsx
@@ -3,19 +3,23 @@ import { useMDXComponents } from '~/mdx-components'
export const generateStaticParams = generateStaticParamsFor('mdxPath')
-// @ts-ignore
-export async function generateMetadata(props) {
+export async function generateMetadata(props: PageProps) {
const params = await props.params
- const { metadata } = await importPage(params.mdxPath)
+ const { metadata } = await importPage(params.mdxPath, params.lang)
return metadata
}
+type PageProps = Readonly<{
+ params: Promise<{
+ mdxPath: string[]
+ lang: string
+ }>
+}>
const Wrapper = useMDXComponents().wrapper
-// @ts-ignore
-export default async function Page(props) {
+export default async function Page(props: PageProps) {
const params = await props.params
- const result = await importPage(params.mdxPath)
+ const result = await importPage(params.mdxPath, params.lang)
const { default: MDXContent, toc, metadata } = result
return (
}) {
+ const { lang } = await params
+
+ const dict = await getDictionary(lang as Locale)
+ const pageMap = await getPageMap(`/${lang}`)
+
+ const banner = () => {
+ return (
+
+
+
+ )
+ }
+
+ const navbar = () => {
+ return (
+ }
+ chatLink='https://discord.gg/p7kWbxDx'
+ />
+ )
+ }
+
+ return (
+
+
+
+ }
+ docsRepositoryBase='https://github.com/CreateWise/createwise-docs'
+ editLink={dict.editPage}
+ sidebar={{ defaultMenuCollapseLevel: 2 }}
+ pageMap={pageMap}
+ lastUpdated={{dict.lastUpdated}}
+ i18n={[
+ { locale: 'en', name: 'English' },
+ { locale: 'zh', name: '简体中文' },
+ ]}
+ themeSwitch={{
+ dark: dict.dark,
+ light: dict.light,
+ system: dict.system,
+ }}
+ nextThemes={{ defaultTheme: 'system' }}
+ feedback={{
+ content: dict.feedback,
+ labels: '',
+ }}
+ >
+ {children}
+
+
+
+ )
+}
diff --git a/src/app/[lang]/not-found.ts b/src/app/[lang]/not-found.ts
new file mode 100644
index 0000000..9c26662
--- /dev/null
+++ b/src/app/[lang]/not-found.ts
@@ -0,0 +1 @@
+export { NotFoundPage as default } from 'nextra-theme-docs'
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
deleted file mode 100644
index 82544a7..0000000
--- a/src/app/layout.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-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'
-import type { ReactNode } from 'react'
-import { Logo } from '~/components/logo'
-import '~/styles/globals.css'
-
-export const metadata = {
- metadataBase: new URL('https://nextra.site'),
- title: {
- template: '%s - CreateWise',
- },
- description: 'CreateWise: the Next.js site builder',
- applicationName: 'CreateWise',
- generator: 'Next.js',
- appleWebApp: {
- title: 'CreateWise',
- },
- other: {
- 'msapplication-TileImage': '/ms-icon-144x144.png',
- 'msapplication-TileColor': '#fff',
- },
- twitter: {
- site: 'https://nextra.site',
- },
-}
-
-export default async function RootLayout({
- children,
-}: { children: ReactNode }) {
- return (
-
-
- CreateWise}
- navbar={} />}
- footer={}
- editLink='Edit this page on GitHub'
- docsRepositoryBase='https://github.com/shuding/nextra/blob/main/examples/docs'
- sidebar={{ defaultMenuCollapseLevel: 1 }}
- pageMap={await getPageMap()}
- >
- {children}
-
-
-
- )
-}
diff --git a/src/content/_meta.js b/src/content/_meta.js
deleted file mode 100644
index b418a01..0000000
--- a/src/content/_meta.js
+++ /dev/null
@@ -1,7 +0,0 @@
-export default {
- index: '',
- 'get-started': '',
- features: '',
- themes: '',
- advanced: '',
-}
diff --git a/src/content/advanced/code-highlighting.mdx b/src/content/advanced/code-highlighting.mdx
deleted file mode 100644
index 7bf744f..0000000
--- a/src/content/advanced/code-highlighting.mdx
+++ /dev/null
@@ -1,56 +0,0 @@
-# Code Highlighting
-
-Nextra uses [Shiki](https://shiki.style) and
-[Rehype Pretty Code](https://github.com/FormidableLabs/prism-react-renderer) to
-highlight the code blocks. This section covers how you can customize it.
-
-## Meta strings
-
-### Highlight lines
-
-````mdx
-```jsx {1,3-5}
-import 'nextra-theme-docs/style.css'
-
-export default function Nextra({ Component, pageProps }) {
- const getLayout = Component.getLayout || (page => page)
- return getLayout()
-}
-```
-````
-
-```jsx {1,4-5}
-import 'nextra-theme-docs/style.css'
-
-export default function Nextra({ Component, pageProps }) {
- const getLayout = Component.getLayout || (page => page)
- return getLayout()
-}
-```
-
-### Title
-
-````mdx
-```jsx filename="_app.js"
-import 'nextra-theme-docs/style.css'
-
-export default function Nextra({ Component, pageProps }) {
- const getLayout = Component.getLayout || (page => page)
- return getLayout()
-}
-```
-````
-
-```jsx filename="_app.js"
-import 'nextra-theme-docs/style.css'
-
-export default function Nextra({ Component, pageProps }) {
- const getLayout = Component.getLayout || (page => page)
- return getLayout()
-}
-```
-
-## Supported Languages
-
-You can find a list of supported languages
-[here](https://github.com/shikijs/shiki/blob/main/docs/languages.md).
diff --git a/src/content/en/_meta.ts b/src/content/en/_meta.ts
new file mode 100644
index 0000000..8ec8567
--- /dev/null
+++ b/src/content/en/_meta.ts
@@ -0,0 +1,5 @@
+export default {
+ index: 'Introduction',
+ guide: 'Guide',
+ advanced: 'Advanced',
+}
diff --git a/src/content/en/advanced/demo.mdx b/src/content/en/advanced/demo.mdx
new file mode 100644
index 0000000..383f1df
--- /dev/null
+++ b/src/content/en/advanced/demo.mdx
@@ -0,0 +1 @@
+# Todo 2
\ No newline at end of file
diff --git a/src/content/en/guide/_meta.ts b/src/content/en/guide/_meta.ts
new file mode 100644
index 0000000..b192224
--- /dev/null
+++ b/src/content/en/guide/_meta.ts
@@ -0,0 +1,3 @@
+export default {
+ demo: '',
+}
diff --git a/src/content/en/guide/demo.mdx b/src/content/en/guide/demo.mdx
new file mode 100644
index 0000000..109d59d
--- /dev/null
+++ b/src/content/en/guide/demo.mdx
@@ -0,0 +1 @@
+# Todo 1
diff --git a/src/content/en/index.mdx b/src/content/en/index.mdx
new file mode 100644
index 0000000..e10b99d
--- /dev/null
+++ b/src/content/en/index.mdx
@@ -0,0 +1 @@
+# Introduction
diff --git a/src/content/features/_meta.js b/src/content/features/_meta.js
deleted file mode 100644
index cb82d13..0000000
--- a/src/content/features/_meta.js
+++ /dev/null
@@ -1,8 +0,0 @@
-export default {
- mdx: '',
- ssg: '',
- i18n: '',
- image: '',
- themes: '',
- latex: '',
-}
diff --git a/src/content/features/i18n.mdx b/src/content/features/i18n.mdx
deleted file mode 100644
index 60aff21..0000000
--- a/src/content/features/i18n.mdx
+++ /dev/null
@@ -1,54 +0,0 @@
-# Next.js I18n
-
-> [!NOTE]
->
-> This feature is only available in the docs theme.
-
-Nextra supports
-[Next.js Internationalized Routing](https://nextjs.org/docs/advanced-features/i18n-routing)
-out of the box.
-
-To add multi-language pages to your Nextra application, just need to config
-`i18n` in `next.config.mjs`:
-
-```js filename="next.config.mjs"
-import nextra from 'nextra'
-
-const withNextra = nextra({
- theme: 'nextra-theme-docs',
- themeConfig: './theme.config.js'
-})
-
-export default withNextra({
- i18n: {
- locales: ['en', 'zh', 'de'],
- defaultLocale: 'en'
- }
-})
-```
-
-Then, add the locale codes to your file extensions (required for the default
-locale too):
-
-```text
-/pages
- index.en.md
- index.zh.md
- index.de.md
- meta.en.json
- meta.zh.json
- meta.de.json
- ...
-```
-
-Finally, add the `i18n` option to your `theme.config.js` to configure the
-language dropdown:
-
-```jsx filename="theme.config.js"
-i18n: [
- { locale: 'en', text: 'English' },
- { locale: 'zh', text: '中文' },
- { locale: 'de', text: 'Deutsch' },
- { locale: 'ar', text: 'العربية', direction: 'rtl' }
-]
-```
diff --git a/src/content/features/image.mdx b/src/content/features/image.mdx
deleted file mode 100644
index fc42214..0000000
--- a/src/content/features/image.mdx
+++ /dev/null
@@ -1,16 +0,0 @@
-# Next.js Image
-
-## Static Image
-
-> [!NOTE]
->
-> This feature is enabled via `staticImage: true` in the Nextra config by
-> default.
-
-Nextra also supports automatic static image imports, you no longer need to
-specify the width and height of the image manually, and you can directly use the
-Markdown syntax to display the same image:
-
-With Next.js Image, there will be no layout shift, and a beautiful blurry
-placeholder will be shown by default when loading the images:
-
diff --git a/src/content/features/latex.mdx b/src/content/features/latex.mdx
deleted file mode 100644
index 3766871..0000000
--- a/src/content/features/latex.mdx
+++ /dev/null
@@ -1,33 +0,0 @@
----
-links:
- - rel: stylesheet
- href: 'https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.css'
----
-
-# LaTeX
-
-Nextra uses [KaTeX](https://katex.org/) to render LaTeX expressions directly in
-MDX. To enable LaTeX support, you must add the following to your
-`next.config.mjs`:
-
-```js filename="next.config.mjs"
-import nextra from 'nextra'
-
-const withNextra = nextra({
- latex: true
-})
-
-export default withNextra()
-```
-
-Using LaTeX within MDX is as simple as wrapping your expression in `$$` or `$`.
-For example, the following code
-
-```latex
-$\sqrt{a^2 + b^2}$
-```
-
-will be rendered as: $\sqrt{a^2 + b^2}$
-
-To learn more about KaTeX and its supported functions, visit their
-[documentation](https://katex.org/docs/supported.html).
diff --git a/src/content/features/mdx.mdx b/src/content/features/mdx.mdx
deleted file mode 100644
index e1e48ce..0000000
--- a/src/content/features/mdx.mdx
+++ /dev/null
@@ -1,159 +0,0 @@
-import { compileMdx } from 'nextra/compile'
-import { Callout } from 'nextra/components'
-import { MDXRemote } from 'nextra/mdx-remote'
-
-# MDX
-
-With Nextra, all your `.md` and `.mdx` files under the pages directory will be
-rendered with [MDX](https://mdxjs.com/about), it's an advanced Markdown format
-with React component support.
-
-You can use import and use React components inside your Markdown files like
-this:
-
-export async function Demo() {
- const mdx = `import { Callout } from 'nextra/components'
-
-**Markdown With React Components**
-
-
- **MDX** (the library), at its core, transforms MDX (the syntax) to JSX. It
- receives an MDX string and outputs a _JSX string_. It does this by parsing the
- MDX document to a syntax tree and then generates a JSX document from that
- tree.
-`
- const rawJs = await compileMdx(`~~~mdx filename="example.mdx"
-${mdx}
-~~~
-
-Generates:
-
-${mdx}`)
- return
-}
-
-
-
-## Headings
-
-# **Hello**, This Is a _Title_ Inside `h1`
-
-## **Hello**, This Is a _Title_ Inside `h2`
-
-### **Hello**, This Is a _Title_ Inside `h3`
-
-#### **Hello**, This Is a _Title_ Inside `h4`
-
-##### **Hello**, This Is a _Title_ Inside `h5`
-
-###### **Hello**, This Is a _Title_ Inside `h6`
-
-## List
-
-1. one
-1. two
-1. three
-
-- one
-- two
-- three
-
-## Task List
-
-```mdx
-- [x] Write the press release
-- [ ] Update the website
-- [ ] Contact the media
-```
-
-Renders
-
-- [x] Write the press release
-- [ ] Update the website
-- [ ] Contact the media
-
-## Syntax Highlighting
-
-Automatic syntax highlighting
-
-````mdx
-```js
-console.log('hello, world')
-```
-````
-
-Renders:
-
-```js
-console.log('hello, world')
-```
-
-You can also add the `{line|range}` modifier to highlight specific lines:
-
-````mdx
-```jsx {4,6-8}
-import useSWR from 'swr'
-
-function Profile() {
- const { data, error } = useSWR('/api/user', fetcher)
-
- if (error) return failed to load
- if (!data) return loading...
- return hello {data.name}!
-}
-```
-````
-
-```jsx {4,6-8}
-import useSWR from 'swr'
-
-function Profile() {
- const { data, error } = useSWR('/api/user', fetcher)
-
- if (error) return failed to load
- if (!data) return loading...
- return hello {data.name}!
-}
-```
-
-## Inline Code
-
-You can use \`content\` to wrap inline code content like: `let x = 1`.
-
-## Blockquote
-
-> Where some people measure progress in answers-right per test or tests-passed
-> per year, we are more interested in Sistine-Chapel-Ceilings per Lifetime.
->
-> — Alan Kay, A Personal Computer for Children of All Ages
-
-Nested quotes:
-
-> > Where some people measure progress in answers-right per test or tests-passed
-> > per year, we are more interested in Sistine-Chapel-Ceilings per Lifetime.
-> >
-> > — Alan Kay, A Personal Computer for Children of All Ages
->
-> This is **great**.
->
-> — Shu Ding.
-
-## Table
-
-| Syntax | Description | Test Text |
-| :------------ | :---------: | ----------: |
-| Header | Title | Here's this |
-| Paragraph | Text | And more |
-| Strikethrough | | ~~Text~~ |
-
-## React Components
-
-React components and Markdown can be **mixed together**, for instance:
-
-```mdx
-Give [**Nextra**](https://github.com/shuding/nextra) a star!
-```
-
-Renders:
-
-Give [**Nextra**](https://github.com/shuding/nextra) a star!
diff --git a/src/content/features/ssg.mdx b/src/content/features/ssg.mdx
deleted file mode 100644
index ce7c8c2..0000000
--- a/src/content/features/ssg.mdx
+++ /dev/null
@@ -1,41 +0,0 @@
-# Next.js SSG
-
-With Next.js, you can pre-render your page using
-[Static Generation (SSG)](https://nextjs.org/docs/basic-features/pages#static-generation-recommended).
-Your pages will be generated at build time and statically served to visitors. It
-can also be cached by a CDN to maximize the performance.
-
-This is supported by Nextra too. Here's an example:
-
-export async function Stars() {
- let stars = 0
- try {
- const response = await fetch('https://api.github.com/repos/shuding/nextra')
- const repo = await response.json()
- stars = repo.stargazers_count
- } catch {
- /* Ignore if there is an error, due rate limiting on CI */
- }
- return {stars}
-}
-
-> Nextra has stars on GitHub!
-
-The number above was generated at build time via MDX server components. With
-[Incremental Static Regeneration](https://nextjs.org/docs/basic-features/data-fetching#incremental-static-regeneration)
-enabled, it will be kept up to date.
-
----
-
-Here's the MDX code for the example above:
-
-```js filename="ssg.mdx"
-export async function Stars() {
- const response = await fetch(`https://api.github.com/repos/shuding/nextra`)
- const repo = await response.json()
- const stars = repo.stargazers_count || 0
- return {stars}
-}
-
-> Nextra has stars on GitHub!
-```
diff --git a/src/content/features/themes.mdx b/src/content/features/themes.mdx
deleted file mode 100644
index 3aca951..0000000
--- a/src/content/features/themes.mdx
+++ /dev/null
@@ -1,16 +0,0 @@
-# Themes
-
-Nextra itself is basically a plugin that normalizes your Markdown routes in
-Next.js into structural data, and it doesn't handle any styling related thing. A
-**theme** is what renders your actual pages, it works like a layout component in
-React.
-
-Nextra has 2 official themes that you can use:
-
-- [Docs Theme](/themes/docs)
-- [Blog Theme](/themes/blog)
-
-You can also extend your own themes. Here's a great starter example by
-[@jaredpalmer](https://github.com/jaredpalmer):
-
-- [Nextra Blank Custom Theme/Boilerplate Example](https://github.com/jaredpalmer/nextra-blank-custom-theme)
diff --git a/src/content/get-started.mdx b/src/content/get-started.mdx
deleted file mode 100644
index ccd61e7..0000000
--- a/src/content/get-started.mdx
+++ /dev/null
@@ -1,111 +0,0 @@
-import { Steps } from 'nextra/components'
-
-# Get Started
-
-## Quick Start with Vercel
-
-You can start by creating your own Nextra site and deploying to Vercel by
-clicking the link:
-
-Vercel will create the Nextra repository and deploy the site for you with just a
-few clicks. Once done, every change in the repository will be deployed
-automatically.
-
-## Create Manually
-
-Nextra works like a Next.js plugin, and it accepts a theme config (layout) to
-render the page. To start: [^3]
-
-
-### Install Next.js, Nextra and React [^1]
-
-```sh npm2yarn
-npm i react react-dom next nextra
-```
-
-### Install the docs theme [^2]
-
-```sh npm2yarn
-npm i nextra-theme-docs
-```
-
-### Create the following Next.js config and theme config under the root directory
-
-```js filename="next.config.mjs"
-import nextra from 'nextra'
-
-const withNextra = nextra({
- theme: 'nextra-theme-blog',
- themeConfig: './theme.config.js'
-})
-export default withNextra()
-```
-
-### Create a `theme.config.js` file for the docs theme
-
-```js filename="theme.config.js"
-export default {
- project: {
- link: 'https://github.com/shuding/nextra' // GitHub link in the navbar
- },
- docsRepositoryBase: 'https://github.com/shuding/nextra/blob/master', // base URL for the docs repository
- getNextSeoProps: () => ({ titleTemplate: '%s – Nextra' }),
- navigation: true,
- darkMode: true,
- footer: {
- text: `MIT ${new Date().getFullYear()} © Shu Ding.`
- },
- editLink: {
- text: 'Edit this page on GitHub'
- },
- logo: (
- <>
-
- Next.js Static Site Generator
- >
- ),
- head: (
- <>
-
-
-
- >
- ),
- primaryHue: {
- dark: 204,
- light: 212
- }
-}
-```
-
-> [!NOTE]
->
-> More configuration options for the docs theme can be found
-> [here](/themes/docs/configuration).
-
-### You are good to go! Run `next dev` to start
-
-
-
----
-
-
-
-> [!NOTE]
->
-> Any `.md` or `.mdx` file will turn into a doc page and be displayed in
-> sidebar. You can also create a `_meta.js` file to customize the page order and
-> title.
Check the source code: https://github.com/shuding/nextra for
-> more information.
-
-> [!TIP]
->
-> You can also use
-> [`