Torihaji's Growth Diary

Little by little, no hurry.

BlockNote を使って遊んでみる.

はじめに

BlockNoteはWYSWIGなEditor。

What you see is what you get 。

みたまんまのものをgetできるよ。というエディタ。

MarkdownとかHTMLとかも行けるみたいで、 Editorjsと違ってなんか強そうということで触ってみる。

深掘りはやる気次第。

敵情視察みたいな感じ。

Next.jsのinstall

npx create-next-app@latest
Need to install the following packages:
create-next-app@14.2.15
Ok to proceed? (y) y

✔ What is your project named? … block_note_sample
✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … No
✔ Would you like to use `src/` directory? … No
✔ Would you like to use App Router? (recommended) … No
✔ Would you like to customize the default import alias (@/*)? … No

少ししたら作れる。

cd block_note_sample

試しにローカルサーバを立ち上げる

npm run dev

http://localhost:3000 開いて下記の画面が開いたらOK

githubのセットアップ

github開いて、リモートリポジトリ作って、リポジトリの設定

git remote add origin https://github.com/(ユーザ名)/block_note_sample.git
git branch -M main
git push -u origin main

BlockNoteを入れる

www.blocknotejs.org

基本的にこの流れに沿っていく。

ものを入れる

npm install @blocknote/core @blocknote/react @blocknote/mantine

入ったので試しに 公式のまんま使ってみる。

pagesディレクトリ配下に note.tsxを作成してその中に、

import { BlockNoteView } from "@blocknote/mantine";
import { useCreateBlockNote } from "@blocknote/react";

const NoteIndex = () => {
  // Creates a new editor instance.
  const editor = useCreateBlockNote();

  // Renders the editor instance using a React component.
  return <BlockNoteView editor={editor} />;
};

export default NoteIndex;

ローカルサーバ立ち上げて、localhost:3000/note にアクセス

よくあるやつ。

SSRだから、サーバの方でブラウザ用のグローバル変数(window)を使おうとして怒られてる。

Next.jsで「document is not defined」と怒られたときの対処法 #React - Qiita

これはEditorjsの時でもあった。

このようなエディタのライブラリは クライアントサイドでのみ動くもの。

事実、公式のドキュメントにもそう書いてある。

Next.js usage (or other server-side React frameworks) Are you using Next.js (create-next-app)? Because BlockNote is a client-only component, make sure to disable server-side rendering of BlockNote. Read our guide on setting up Next.js + BlockNote

ということで公式の言う通りの対処を実施する。

今回は dynamicインポートを使う。

Next.js and BlockNote - BlockNote

ということで新しく componentsディレクトリを作成し、その下にeditor.tsxを作成して下記を記述

import { BlockNoteView } from "@blocknote/mantine";
import { useCreateBlockNote } from "@blocknote/react";

const Editor = () => {
  // Creates a new editor instance.
  const editor = useCreateBlockNote();

  // Renders the editor instance using a React component.
  return <BlockNoteView editor={editor} />;
};

export default Editor;

次に元々書いていたnote.tsxを以下のように修正

import dynamic from "next/dynamic";

const Editor = dynamic(() => import("../components/editor"), { ssr: false });

const Note = () => {
  return (
    <div>
      <Editor />
    </div>
  );
};

export default Note;

localhost:3000/note を見てみると

あら。なんかおかしい。

あれか、cssつけてないからか。

ということで公式のもの入れ忘れたので入れる

import "@blocknote/core/fonts/inter.css";
import "@blocknote/mantine/style.css";

うん、なった。これで無料か。すごい。

Editorjs入れる時あれだけ苦労したのに。

操作感はめちゃめちゃいい。

Notionみたい

この2、3行書いただけで分かったこと。

良いとこ

  • Header のデザインが綺麗
  • コマンドショートカットがある。
  • 番号付きリスト、箇条書きのリストにおいて綺麗
  • リストにおいてTab 、シフト + Tabで階層移動ができる。
  • 階層移動の際の動きがスムーズ。
  • チェックボックスがあり、階層構造がある。
  • インラインツールバーが充実してる。(文字太くしたり文字色変えたり色々できる)
  • 表も記述可能。

悪いとこ

  • 画像や動画、ファイルの添付ができない?
  • Youtubeの共有URL貼り付けても文字列として認識される?

=> 多分画像とかは追加で設定する必要があるのか、

ただNo Configでここまで行けるのはすごいと思う。

もう少し続けてみる。

とにかく今やったことはこの2つだけ。

  • pages/note.tsxに公式のものをコピーしただけ。
  • components/editor.tsxに公式のものをコピーしただけ。

これだけでここまで行けるのは。何度も言うけどすごいと思う。

もう少し深掘り

  const editor = useCreateBlockNote();

こいつに引数は設定可能らしい。

function useCreateBlockNote(
  options?: BlockNoteEditorOptions,
  deps?: React.DependencyList = [],
): BlockNoteEditor;

とりあえずoptionsという方に色々設定可能みたい。

Editorjsのtoolに相当するものらしい。

type BlockNoteEditorOptions = {
  initialContent?: PartialBlock[];
  domAttributes?: Record<string, string>;
  defaultStyles?: boolean;
  uploadFile?: (file: File) => Promise<string>;
  collaboration?: CollaborationOptions;
  dictionary?: Dictionary;
  schema?: BlockNoteSchema;
  trailingBlock?: boolean;
  animations?: boolean;
};

Editorjsのdataに相当するのはこのinitialContentらしい。

あと関係ありそうなのは uploadFileとかいう関数

次はこれ。

<BlockNoteView editor={editor} />

実際のview。

export type BlockNoteViewProps = {
  editor: BlockNoteEditor;
  editable?: boolean;
  onSelectionChange?: () => void;
  onChange?: () => void;
  theme?:
    | "light"
    | "dark"
    | Theme
    | {
        light: Theme;
        dark: Theme;
      };
  formattingToolbar?: boolean;
  linkToolbar?: boolean;
  sideMenu?: boolean;
  slashMenu?: boolean;
  emojiPicker?: boolean;
  filePanel?: boolean;
  tableHandles?: boolean;
  children?:
} & HTMLAttributes<HTMLDivElement>;

渡せるのはこいつららしい。

ぱっと見使えそうというか、関係ありそうなのは onChangeとか。

エディタの内容が変わるのを検知して発火するみたい。

実際にbackendとかと連携して使っていくとなるとこの子を設定する必要があると思う。

出力形式は JSONみたい。特定の型に沿ったJSONを吐き出すみたい。

これもEditorjsと同じみたい。

JSON.stringfyして云々するやつ。

なんかここまで使ってみたけどなんとなくEditorjsと同じ感じで使っていけそうということがわかった。

さらなる深掘りはまた今度にしよう

飽きた。

終わりに

ほー。

強そう。何より"おしゃれ"。

ただtailwindcss使ってないので入れたらどんな感じで競合するかはわからない。

またBlocknoteのcssと競合しないかが心配。

Editorjsの時は Headerがただの文字列として表示されて、原因がtailwindだったということがあったから

まぁ一旦終了。