diff --git a/.vscode/settings.json b/.vscode/settings.json index 7469bd1c70..7c24081186 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -18,5 +18,8 @@ "search.defaultViewMode": "tree", "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[mdx]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" } } diff --git a/docs/.eslintrc.json b/docs/.eslintrc.json index 01aef10904..3f47543412 100644 --- a/docs/.eslintrc.json +++ b/docs/.eslintrc.json @@ -1,10 +1,5 @@ { - "extends": "next/core-web-vitals", - "parser": "@typescript-eslint/parser", - "plugins": ["@typescript-eslint"], "rules": { - "import/extensions": 0, - "@next/next/no-img-element": "off" - }, - "root": true + "import/extensions": 0 + } } diff --git a/docs/.gitignore b/docs/.gitignore index af673ac194..649c9b9df2 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -35,6 +35,11 @@ yarn-error.log* *.tsbuildinfo next-env.d.ts +# database +*.db + # Sentry Config File .env.sentry-build-plugin -*.db \ No newline at end of file +/content/examples/*/* +/components/example/generated/ +/.source/ \ No newline at end of file diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md deleted file mode 100644 index 0b113d1002..0000000000 --- a/docs/DEVELOPMENT.md +++ /dev/null @@ -1,99 +0,0 @@ -# Website Development - -To get started with development of the website, you can follow these steps: - -1. Initialize the DB - -If you haven't already, you can initialize the database with the following command: - -```bash -cd docs && pnpm run init-db -``` - -This will initialize an SQLite database at `./docs/sqlite.db`. - -2. Setup environment variables - -Copy the `.env.example` file to `.env.local` and set the environment variables. - -```bash -cp .env.example .env.local -``` - -If you want to test logging in, or payments see more information below [in the environment variables section](#environment-variables). - -3. Start the development server - -```bash -cd docs && pnpm run dev -``` - -This will start the development server on port 3000. - -## Environment Variables - -### Logging in - -To test logging in, you can set the following environment variables: - -```bash -AUTH_SECRET=test -# Github OAuth optionally -AUTH_GITHUB_ID=test -AUTH_GITHUB_SECRET=test -``` - -Note: the GITHUB_ID and GITHUB_SECRET are optional, but if you want to test logging in with Github you'll need to set them. For local development, you'll need to set the callback URL to `http://localhost:3000/api/auth/callback/github` - -### Payments - -To test payments, you can set the following environment variables: - -```bash -POLAR_ACCESS_TOKEN=test -POLAR_WEBHOOK_SECRET=test -``` - -For testing payments, you'll need access to the polar sandbox which needs to be configured to point a webhook to your local server. This can be configured at: - -You'll need something like [ngrok](https://ngrok.com/) to expose your local server to the internet. - -```bash -ngrok http http://localhost:3000 -``` - -You'll need the webhook to point to ngrok like so: - -``` -https://0000-00-00-000-00.ngrok-free.app/api/auth/polar/webhooks -``` - -With this webhook pointing to your local server, you should be able to test payments. - -### Email sending - -Note, this is not required, if email sending is not configured, the app will log the email it would send to the console. Often this is more convenient for development. - -To test email sending, you can set the following environment variables: - -```bash -SMTP_HOST= -SMTP_USER= -SMTP_PASS= -SMTP_PORT= -SMTP_SECURE=false -``` - -When configured, you'll be able to send emails to the email address you've configured. - -To setup with protonmail, you'll need to go to and create a new SMTP submission token. - -You'll need to set the following environment variables: - -```bash -SMTP_HOST=smtp.protonmail.com -SMTP_USER=my.email@protonmail.com -SMTP_PASS=my-smtp-token -SMTP_PORT=587 -SMTP_SECURE=false -``` diff --git a/docs/README.md b/docs/README.md index ec0577e219..b8e4860113 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,21 +1,105 @@ -# BlockNote Docs +# Website Development -This is the code for the [BlockNote documentation website](https://www.blocknotejs.org). +This is the code for the [BlockNote documentation website](https://www.blocknotejs.org). If you're looking to work on BlockNote itself, check the [`packages`](/packages/) folder. -If you're looking to work on BlockNote itself, check the [`packages`](/packages/) folder. +To get started with development of the website, you can follow these steps: -## Getting Started +1. Initialize the DB -First, run `npm run build` in the repository root. +If you haven't already, you can initialize the database with the following command: -Next, run the development server: +```bash +cd docs && pnpm run init-db +``` + +This will initialize an SQLite database at `./docs/sqlite.db`. + +2. Setup environment variables + +Copy the `.env.example` file to `.env.local` and set the environment variables. + +```bash +cp .env.example .env.local +``` + +If you want to test logging in, or payments see more information below [in the environment variables section](#environment-variables). + +3. Start the development server from within the `./docs` directory. + +```bash +pnpm run dev +``` + +This will start the development server on port 3000. + +## Environment Variables + +### Logging in + +To test logging in, you can set the following environment variables: + +```bash +AUTH_SECRET=test +# Github OAuth optionally +AUTH_GITHUB_ID=test +AUTH_GITHUB_SECRET=test +``` + +Note: the GITHUB_ID and GITHUB_SECRET are optional, but if you want to test logging in with Github you'll need to set them. For local development, you'll need to set the callback URL to `http://localhost:3000/api/auth/callback/github` + +### Payments + +To test payments, you can set the following environment variables: + +```bash +POLAR_ACCESS_TOKEN=test +POLAR_WEBHOOK_SECRET=test +``` + +For testing payments, you'll need access to the polar sandbox which needs to be configured to point a webhook to your local server. This can be configured at: + +You'll need something like [ngrok](https://ngrok.com/) to expose your local server to the internet. + +```bash +ngrok http http://localhost:3000 +``` + +You'll need the webhook to point to ngrok like so: + +``` +https://0000-00-00-000-00.ngrok-free.app/api/auth/polar/webhooks +``` + +With this webhook pointing to your local server, you should be able to test payments. + +### Email sending + +Note, this is not required, if email sending is not configured, the app will log the email it would send to the console. Often this is more convenient for development. + +To test email sending, you can set the following environment variables: ```bash -npm run dev +SMTP_HOST= +SMTP_USER= +SMTP_PASS= +SMTP_PORT= +SMTP_SECURE=false ``` -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. +When configured, you'll be able to send emails to the email address you've configured. + +To setup with protonmail, you'll need to go to and create a new SMTP submission token. + +You'll need to set the following environment variables: + +```bash +SMTP_HOST=smtp.protonmail.com +SMTP_USER=my.email@protonmail.com +SMTP_PASS=my-smtp-token +SMTP_PORT=587 +SMTP_SECURE=false +``` -## Merging +# Contributing -Open a pull request to the [BlockNote GitHub repo](https://github.com/TypeCellOS/BlockNote). Pull requests will automatically be deployed to a preview environment. +To submit your changes, open a pull request to the [BlockNote GitHub repo](https://github.com/TypeCellOS/BlockNote). Pull requests will automatically be deployed to a preview environment. diff --git a/docs/components/pages/landing/community/Community.tsx b/docs/app/(home)/community/Community.tsx similarity index 65% rename from docs/components/pages/landing/community/Community.tsx rename to docs/app/(home)/community/Community.tsx index e0da85e5fa..f17a69c923 100644 --- a/docs/components/pages/landing/community/Community.tsx +++ b/docs/app/(home)/community/Community.tsx @@ -1,8 +1,8 @@ import { FC } from "react"; -import { Contributors } from "@/components/pages/landing/community/Contributors"; -import { Section } from "@/components/pages/landing/shared/Section"; -import { Sponsors } from "@/components/pages/landing/community/Sponsors"; -import { SectionIntro } from "@/components/pages/landing/shared/Headings"; +import { Contributors } from "@/app/(home)/community/Contributors"; +import { Section } from "@/components/Section"; +import { Sponsors } from "@/app/(home)/community/Sponsors"; +import { SectionIntro } from "@/components/Headings"; export const Community: FC = () => (
diff --git a/docs/components/pages/landing/community/Contributors.tsx b/docs/app/(home)/community/Contributors.tsx similarity index 90% rename from docs/components/pages/landing/community/Contributors.tsx rename to docs/app/(home)/community/Contributors.tsx index b88c6e70e9..0b15e9c90e 100644 --- a/docs/components/pages/landing/community/Contributors.tsx +++ b/docs/app/(home)/community/Contributors.tsx @@ -1,9 +1,9 @@ -import { Link } from "nextra-theme-docs"; import Image from "next/image"; -import { DiscordIcon, GitHubIcon } from "nextra/icons"; -import { SectionSubHeader } from "@/components/pages/landing/shared/Headings"; -import { JoinButton } from "@/components/pages/landing/community/JoinButton"; -import { FadeIn } from "@/components/pages/landing/shared/FadeIn"; +import Link from "next/link"; +import { RiDiscordFill, RiGithubFill } from "react-icons/ri"; +import { SectionSubHeader } from "@/components/Headings"; +import { JoinButton } from "@/app/(home)/community/JoinButton"; +import { FadeIn } from "@/components/FadeIn"; // TODO: Use GitHub API function fetchContributors(): { username: string; avatarUrl: string }[] { @@ -114,7 +114,7 @@ export const Contributors = () => ( subtext={ "Join the community of BlockNote developers by contributing code and supporting the project." } - icon={GitHubIcon} + icon={} linkTitle={"See our repository"} linkUrl={"https://github.com/TypeCellOS/BlockNote"} /> @@ -123,7 +123,7 @@ export const Contributors = () => ( subtext={ "Ask questions, discuss features, and share your work with other BlockNote users on Discord." } - icon={DiscordIcon} + icon={} linkTitle={"Join our Server"} linkUrl={"https://discord.gg/Qc2QTTH5dF"} /> diff --git a/docs/components/pages/landing/community/JoinButton.tsx b/docs/app/(home)/community/JoinButton.tsx similarity index 76% rename from docs/components/pages/landing/community/JoinButton.tsx rename to docs/app/(home)/community/JoinButton.tsx index 8436b40053..ec1ce485c3 100644 --- a/docs/components/pages/landing/community/JoinButton.tsx +++ b/docs/app/(home)/community/JoinButton.tsx @@ -1,24 +1,20 @@ -import { Link } from "nextra-theme-docs"; -import { ComponentProps, FC } from "react"; +import Link from "next/link"; +import { ReactNode } from "react"; export const JoinButton = (props: { text: string; subtext: string; - icon: FC>; + icon: ReactNode; linkTitle: string; linkUrl: string; }) => { - const Icon = props.icon; - return (
-
- -
+
{props.icon}

- {props.name} - {props.name} - {props.tagline && (
{props.tagline} diff --git a/docs/components/pages/landing/community/Sponsors.tsx b/docs/app/(home)/community/Sponsors.tsx similarity index 56% rename from docs/components/pages/landing/community/Sponsors.tsx rename to docs/app/(home)/community/Sponsors.tsx index 690758d5ab..1dcf1cbb05 100644 --- a/docs/components/pages/landing/community/Sponsors.tsx +++ b/docs/app/(home)/community/Sponsors.tsx @@ -1,30 +1,30 @@ import { SponsorCard, SponsorCardProps, -} from "@/components/pages/landing/community/SponsorCard"; -import { FadeIn } from "@/components/pages/landing/shared/FadeIn"; -import { SectionSubHeader } from "@/components/pages/landing/shared/Headings"; +} from "@/app/(home)/community/SponsorCard"; +import { FadeIn } from "@/components/FadeIn"; +import { SectionSubHeader } from "@/components/Headings"; -import agree from "../../../../public/img/sponsors/agree.png"; -import atuin from "../../../../public/img/sponsors/atuin.png"; -import capitolDark from "../../../../public/img/sponsors/capitolDark.svg"; -import capitolLight from "../../../../public/img/sponsors/capitolLight.svg"; -import deepOrigin from "../../../../public/img/sponsors/deepOrigin.svg"; -import dinumDark from "../../../../public/img/sponsors/dinumDark.svg"; -import dinumLight from "../../../../public/img/sponsors/dinumLight.svg"; -import fermatDark from "../../../../public/img/sponsors/fermatDark.svg"; -import fermatLight from "../../../../public/img/sponsors/fermatLight.svg"; -import nlnetDark from "../../../../public/img/sponsors/nlnetDark.svg"; -import nlnetLight from "../../../../public/img/sponsors/nlnetLight.svg"; -import notePlanDark from "../../../../public/img/sponsors/notePlanDark.png"; -import notePlanLight from "../../../../public/img/sponsors/notePlanLight.png"; -import poggioDark from "../../../../public/img/sponsors/poggioDark.svg"; -import poggioLight from "../../../../public/img/sponsors/poggioLight.svg"; -import twentyDark from "../../../../public/img/sponsors/twentyDark.png"; -import twentyLight from "../../../../public/img/sponsors/twentyLight.png"; -import typeCellDark from "../../../../public/img/sponsors/typeCellDark.svg"; -import typeCellLight from "../../../../public/img/sponsors/typeCellLight.svg"; -import zendis from "../../../../public/img/sponsors/zendis.svg"; +import agree from "@/public/img/sponsors/agree.png"; +import atuin from "@/public/img/sponsors/atuin.png"; +import capitolDark from "@/public/img/sponsors/capitolDark.svg"; +import capitolLight from "@/public/img/sponsors/capitolLight.svg"; +import deepOrigin from "@/public/img/sponsors/deepOrigin.svg"; +import dinumDark from "@/public/img/sponsors/dinumDark.svg"; +import dinumLight from "@/public/img/sponsors/dinumLight.svg"; +import fermatDark from "@/public/img/sponsors/fermatDark.svg"; +import fermatLight from "@/public/img/sponsors/fermatLight.svg"; +import nlnetDark from "@/public/img/sponsors/nlnetDark.svg"; +import nlnetLight from "@/public/img/sponsors/nlnetLight.svg"; +import notePlanDark from "@/public/img/sponsors/notePlanDark.png"; +import notePlanLight from "@/public/img/sponsors/notePlanLight.png"; +import poggioDark from "@/public/img/sponsors/poggioDark.svg"; +import poggioLight from "@/public/img/sponsors/poggioLight.svg"; +import twentyDark from "@/public/img/sponsors/twentyDark.png"; +import twentyLight from "@/public/img/sponsors/twentyLight.png"; +import typeCellDark from "@/public/img/sponsors/typeCellDark.svg"; +import typeCellLight from "@/public/img/sponsors/typeCellLight.svg"; +import zendis from "@/public/img/sponsors/zendis.svg"; export const sponsorsCardData: SponsorCardProps[] = [ { diff --git a/docs/components/pages/landing/faq/FAQ.tsx b/docs/app/(home)/faq/FAQ.tsx similarity index 93% rename from docs/components/pages/landing/faq/FAQ.tsx rename to docs/app/(home)/faq/FAQ.tsx index 109c9ff3ec..f4fe21e0c1 100644 --- a/docs/components/pages/landing/faq/FAQ.tsx +++ b/docs/app/(home)/faq/FAQ.tsx @@ -1,6 +1,6 @@ -import { SectionIntro } from "@/components/pages/landing/shared/Headings"; -import { Section } from "@/components/pages/landing/shared/Section"; -import { Link } from "nextra-theme-docs"; +import { SectionIntro } from "@/components/Headings"; +import { Section } from "@/components/Section"; +import Link from "next/link"; const faqs = [ { diff --git a/docs/components/pages/landing/features/FeatureCard.tsx b/docs/app/(home)/features/FeatureCard.tsx similarity index 61% rename from docs/components/pages/landing/features/FeatureCard.tsx rename to docs/app/(home)/features/FeatureCard.tsx index c731c4730b..7cde6026b9 100644 --- a/docs/components/pages/landing/features/FeatureCard.tsx +++ b/docs/app/(home)/features/FeatureCard.tsx @@ -1,3 +1,4 @@ +import ThemedImage from "@/components/ThemedImage"; import Image from "next/image"; import { IconType } from "react-icons"; @@ -16,18 +17,17 @@ export function FeatureCard(props: FeatureCardProps) { return (
{props.thumbnail && ( -
- {props.title} - +
diff --git a/docs/components/pages/landing/features/Features.tsx b/docs/app/(home)/features/Features.tsx similarity index 79% rename from docs/components/pages/landing/features/Features.tsx rename to docs/app/(home)/features/Features.tsx index d70fd8ef72..713e274739 100644 --- a/docs/components/pages/landing/features/Features.tsx +++ b/docs/app/(home)/features/Features.tsx @@ -11,20 +11,20 @@ import { BiLogoMarkdown, BiSolidWrench, } from "react-icons/bi"; -import { Section } from "@/components/pages/landing/shared/Section"; +import { Section } from "@/components/Section"; import { FeatureCard, FeatureCardProps, -} from "@/components/pages/landing/features/FeatureCard"; -import { FadeIn } from "@/components/pages/landing/shared/FadeIn"; -import { SectionIntro } from "@/components/pages/landing/shared/Headings"; +} from "@/app/(home)/features/FeatureCard"; +import { FadeIn } from "@/components/FadeIn"; +import { SectionIntro } from "@/components/Headings"; -import worksOutOfTheBoxLight from "../../../../public/img/features/works_out_of_the_box_light.gif"; -import worksOutOfTheBoxDark from "../../../../public/img/features/works_out_of_the_box_dark.gif"; -import blockBasedDesignLight from "../../../../public/img/features/block_based_design_light.gif"; -import blockBasedDesignDark from "../../../../public/img/features/block_based_design_dark.gif"; -import collaborationLight from "../../../../public/img/features/collaboration_light.gif"; -import collaborationDark from "../../../../public/img/features/collaboration_dark.gif"; +import worksOutOfTheBoxLight from "@/public/img/features/works_out_of_the_box_light.gif"; +import worksOutOfTheBoxDark from "@/public/img/features/works_out_of_the_box_dark.gif"; +import blockBasedDesignLight from "@/public/img/features/block_based_design_light.gif"; +import blockBasedDesignDark from "@/public/img/features/block_based_design_dark.gif"; +import collaborationLight from "@/public/img/features/collaboration_light.gif"; +import collaborationDark from "@/public/img/features/collaboration_dark.gif"; export const featuresCardData: FeatureCardProps[] = [ { diff --git a/docs/app/(home)/hero/Demo.tsx b/docs/app/(home)/hero/Demo.tsx new file mode 100644 index 0000000000..b2c6fd4be2 --- /dev/null +++ b/docs/app/(home)/hero/Demo.tsx @@ -0,0 +1,32 @@ +"use client"; + +import dynamic from "next/dynamic"; +import ThemedImage from "@/components/ThemedImage"; +import tryHereImageDark from "@/public/img/assets/try.dark.svg"; +import tryHereImageLight from "@/public/img/assets/try.svg"; + +function TryHereImage() { + return ( + + ); +} + +const DemoEditor = dynamic(() => import("@/app/(home)/hero/DemoEditor"), { + ssr: false, +}); + +export function Demo() { + return ( +
+
+
+ +
+ +
+ ); +} diff --git a/docs/components/pages/landing/hero/DemoEditor.tsx b/docs/app/(home)/hero/DemoEditor.tsx similarity index 95% rename from docs/components/pages/landing/hero/DemoEditor.tsx rename to docs/app/(home)/hero/DemoEditor.tsx index 8c81ae7243..3712a843ce 100644 --- a/docs/components/pages/landing/hero/DemoEditor.tsx +++ b/docs/app/(home)/hero/DemoEditor.tsx @@ -19,6 +19,7 @@ import { withMultiColumn, } from "@blocknote/xl-multi-column"; import "@blocknote/mantine/style.css"; +import { useTheme } from "next-themes"; import { useCallback, useMemo, useState } from "react"; import YPartyKitProvider from "y-partykit/provider"; import * as Y from "yjs"; @@ -69,7 +70,9 @@ function getUTCDateYYYYMMDD() { return `${year}${formattedMonth}${formattedDay}`; } -export default function DemoEditor(props: { theme?: "light" | "dark" }) { +export default function DemoEditor() { + const { resolvedTheme } = useTheme(); + const [doc, provider] = useMemo(() => { const doc = new Y.Doc(); const provider = new YPartyKitProvider( @@ -128,7 +131,7 @@ export default function DemoEditor(props: { theme?: "light" | "dark" }) { + + + + +

+ ); +} diff --git a/docs/components/pages/landing/hero/Text.tsx b/docs/app/(home)/hero/Text.tsx similarity index 83% rename from docs/components/pages/landing/hero/Text.tsx rename to docs/app/(home)/hero/Text.tsx index 1a36c220ea..6f6aa8fd06 100644 --- a/docs/components/pages/landing/hero/Text.tsx +++ b/docs/app/(home)/hero/Text.tsx @@ -1,8 +1,5 @@ -import { - HeroText, - SectionSubtext, -} from "@/components/pages/landing/shared/Headings"; -import CTAButton from "@/components/pages/landing/shared/CTAButton"; +import { HeroText, SectionSubtext } from "@/components/Headings"; +import CTAButton from "@/components/CTAButton"; export function Text() { return ( diff --git a/docs/components/pages/landing/hero/styles.css b/docs/app/(home)/hero/styles.css similarity index 100% rename from docs/components/pages/landing/hero/styles.css rename to docs/app/(home)/hero/styles.css diff --git a/docs/app/(home)/layout.tsx b/docs/app/(home)/layout.tsx new file mode 100644 index 0000000000..235258e8c5 --- /dev/null +++ b/docs/app/(home)/layout.tsx @@ -0,0 +1,13 @@ +import type { ReactNode } from "react"; +import { HomeLayout } from "fumadocs-ui/layouts/home"; +import { baseOptions } from "@/app/layout.config"; +import { Footer } from "@/components/Footer"; + +export default function Layout({ children }: { children: ReactNode }) { + return ( + <> + {children} +