-
-
Notifications
You must be signed in to change notification settings - Fork 565
feat: server-side processing #451
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
ee11a46
basic server util poc
YousefED cafe24d
add todo
YousefED b38758f
more comments
YousefED 1851894
Merge remote-tracking branch 'origin/main' into feature/server-util
YousefED 8a451d4
wip
YousefED c1dad8a
Merge remote-tracking branch 'origin/main' into feature/server-util
YousefED 8608c50
Merge remote-tracking branch 'origin/main' into feature/server-util
YousefED db17581
update server implementation + tests
YousefED 4d3c819
fix tests
YousefED b5412d8
Merge remote-tracking branch 'origin/main' into feature/server-util
YousefED 3ee979f
add example
YousefED 8cf0143
update snaps
YousefED 26728f4
misc fixes
YousefED 40e8763
fix lint
YousefED 4307b82
fix tests
YousefED 34e4d4f
fix site build
YousefED 1f2b048
useCallback for ref
YousefED cdf570b
remove comment
YousefED a4fdc99
update comments
YousefED 2c26f44
Merge branch 'main' into feature/server-util
YousefED 5e936aa
comment feedback + doc changes
YousefED de4142b
revert style change
YousefED f8de988
add docs
YousefED 3bbe308
move example
YousefED 57a38e5
update docs
YousefED 4cf661b
fix styles
YousefED 33b4f39
fix docs
YousefED File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
{ | ||
"manipulating-blocks":"", | ||
"manipulating-inline-content":"", | ||
"cursor-selections":"", | ||
"converting-blocks":"" | ||
"manipulating-blocks": "", | ||
"manipulating-inline-content": "", | ||
"cursor-selections": "", | ||
"converting-blocks": "", | ||
"server-processing": "" | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
--- | ||
title: Server-side processing | ||
description: Use `ServerBlockNoteEditor` to process Blocks on the server. | ||
imageTitle: Server-side processing | ||
path: /docs/server-side-processing | ||
--- | ||
|
||
import { Example } from "@/components/example"; | ||
import { Callout } from "nextra/components"; | ||
|
||
# Server-side processing | ||
|
||
While you can use the `BlockNoteEditor` on the client side, | ||
you can also use `ServerBlockNoteEditor` from `@blocknote/server-util` to process BlockNote documents on the server. | ||
|
||
For example, use the following code to convert a BlockNote document to HTML on the server: | ||
|
||
```tsx | ||
import { ServerBlockNoteEditor } from "@blocknote/server-util"; | ||
|
||
const editor = ServerBlockNoteEditor.create(); | ||
const html = await editor.blocksToFullHTML(blocks); | ||
``` | ||
|
||
`ServerBlockNoteEditor.create` takes the same BlockNoteEditorOptions as `useCreateBlockNote` and `BlockNoteEditor.create` ([see docs](/docs/editor-basics/setup)), | ||
so you can pass the same configuration (for example, your custom schema) to your server-side BlockNote editor as on the client. | ||
|
||
## Functions for converting blocks | ||
|
||
`ServerBlockNoteEditor` exposes the same functions for [converting blocks as the client side editor](/docs/converting-blocks): | ||
|
||
- `blocksToFullHTML` | ||
- `blocksToHTMLLossy` and `tryParseHTMLToBlocks` | ||
- `blocksToMarkdownLossy` and `tryParseMarkdownToBlocks` | ||
|
||
## Yjs processing | ||
|
||
Additionally, `ServerBlockNoteEditor` provides functions for processing Yjs documents in case you use Yjs collaboration: | ||
|
||
- `yDocToBlocks` or `yXmlFragmentToBlocks`: use this to convert a Yjs document or XML Fragment to BlockNote blocks | ||
- `blocksToYDoc` or `blocksToYXmlFragment`: use this to convert a BlockNote document (blocks) to a Yjs document or XML Fragment | ||
|
||
## React compatibility | ||
|
||
If you use [custom schemas in React](/docs/custom-schemas), you can use the same schema on the server side. | ||
Functions like `blocksToFullHTML` will use your custom React rendering functions to export blocks to HTML, similar to how these functions work on the client. | ||
However, it could be that your React components require access to a React context (e.g. a theme or localization context). | ||
|
||
For these use-cases, we provide a function `withReactContext` that allows you to pass a React context to the server-side editor. | ||
This example exports a BlockNote document to HTML within a React context `YourContext`, so that even Custom Blocks built in React that require `YourContext` will be exported correctly: | ||
|
||
```tsx | ||
const html = await editor.withReactContext( | ||
({ children }) => ( | ||
<YourContext.Provider value={true}>{children}</YourContext.Provider> | ||
), | ||
async () => editor.blocksToFullHTML(blocks), | ||
); | ||
``` |
9 changes: 9 additions & 0 deletions
9
examples/02-backend/04-rendering-static-documents/.bnexample.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"playground": true, | ||
"docs": true, | ||
"author": "yousefed", | ||
"tags": ["server"], | ||
"dependencies": { | ||
"@blocknote/server-util": "latest" | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import "@blocknote/core/fonts/inter.css"; | ||
import "@blocknote/core/style.css"; | ||
|
||
/** | ||
On Server Side, you can use the ServerBlockNoteEditor to render BlockNote documents to HTML. e.g.: | ||
|
||
import { ServerBlockNoteEditor } from "@blocknote/server-util"; | ||
|
||
const editor = ServerBlockNoteEditor.create(); | ||
const html = await editor.blocksToFullHTML(document); | ||
|
||
You can then use render this HTML as a static page or send it to the client. Make sure to include the editor stylesheets: | ||
|
||
import "@blocknote/core/fonts/inter.css"; | ||
import "@blocknote/core/style.css"; | ||
|
||
This example has the HTML hard-coded, but shows at least how the document will be rendered when the appropriate style sheets are loaded. | ||
*/ | ||
|
||
export default function App() { | ||
// This HTML is generated by the ServerBlockNoteEditor.blocksToFullHTML method | ||
const html = `<div class="bn-block-group" data-node-type="blockGroup"> | ||
<div class="bn-block-outer" data-node-type="blockOuter" data-id="1" data-text-color="yellow" data-background-color="blue"> | ||
<div class="bn-block" data-node-type="blockContainer" data-id="1" data-text-color="yellow" data-background-color="blue"> | ||
<div class="bn-block-content" data-content-type="heading" data-text-alignment="right" data-level="2"> | ||
<h2 class="bn-inline-content"> | ||
<strong><u>Heading </u></strong><em><s>2</s></em> | ||
</h2> | ||
</div> | ||
<div class="bn-block-group" data-node-type="blockGroup"> | ||
<div class="bn-block-outer" data-node-type="blockOuter" data-id="2" data-background-color="red"> | ||
<div class="bn-block" data-node-type="blockContainer" data-id="2" data-background-color="red"> | ||
<div class="bn-block-content" data-content-type="paragraph"> | ||
<p class="bn-inline-content">Paragraph</p> | ||
</div> | ||
</div> | ||
</div> | ||
<div class="bn-block-outer" data-node-type="blockOuter" data-id="3"> | ||
<div class="bn-block" data-node-type="blockContainer" data-id="3"> | ||
<div class="bn-block-content" data-content-type="bulletListItem"> | ||
<p class="bn-inline-content">list item</p> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
`; | ||
|
||
// Renders the editor instance using a React component. | ||
return ( | ||
<div className="bn-container"> | ||
<div | ||
className=" bn-default-styles" | ||
dangerouslySetInnerHTML={{ __html: html }} | ||
/> | ||
</div> | ||
); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# Rendering static documents | ||
|
||
This example shows how you can use HTML exported using the `blocksToFullHTML` and render it as a static document (a view-only document, without the editor). You can use this for example if you use BlockNote to edit blog posts in a CMS, but want to display non-editable static, published pages to end-users. | ||
|
||
**Relevant Docs:** | ||
|
||
- [Server-side processing](/docs/editor-api/server-processing) |
14 changes: 14 additions & 0 deletions
14
examples/02-backend/04-rendering-static-documents/index.html
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<html lang="en"> | ||
<head> | ||
<script> | ||
<!-- AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY --> | ||
</script> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Rendering static documents</title> | ||
</head> | ||
<body> | ||
<div id="root"></div> | ||
<script type="module" src="./main.tsx"></script> | ||
</body> | ||
</html> |
11 changes: 11 additions & 0 deletions
11
examples/02-backend/04-rendering-static-documents/main.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY | ||
import React from "react"; | ||
import { createRoot } from "react-dom/client"; | ||
import App from "./App"; | ||
|
||
const root = createRoot(document.getElementById("root")!); | ||
root.render( | ||
<React.StrictMode> | ||
<App /> | ||
</React.StrictMode> | ||
); |
38 changes: 38 additions & 0 deletions
38
examples/02-backend/04-rendering-static-documents/package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
{ | ||
"name": "@blocknote/example-rendering-static-documents", | ||
"description": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY", | ||
"private": true, | ||
"version": "0.12.4", | ||
"scripts": { | ||
"start": "vite", | ||
"dev": "vite", | ||
"build": "tsc && vite build", | ||
"preview": "vite preview", | ||
"lint": "eslint . --max-warnings 0" | ||
}, | ||
"dependencies": { | ||
"@blocknote/core": "latest", | ||
"@blocknote/react": "latest", | ||
"@blocknote/ariakit": "latest", | ||
"@blocknote/mantine": "latest", | ||
"@blocknote/shadcn": "latest", | ||
"react": "^18.3.1", | ||
"react-dom": "^18.3.1", | ||
"@blocknote/server-util": "latest" | ||
}, | ||
"devDependencies": { | ||
"@types/react": "^18.0.25", | ||
"@types/react-dom": "^18.0.9", | ||
"@vitejs/plugin-react": "^4.0.4", | ||
"eslint": "^8.10.0", | ||
"vite": "^4.4.8" | ||
}, | ||
"eslintConfig": { | ||
"extends": [ | ||
"../../../.eslintrc.js" | ||
] | ||
}, | ||
"eslintIgnore": [ | ||
"dist" | ||
] | ||
} |
36 changes: 36 additions & 0 deletions
36
examples/02-backend/04-rendering-static-documents/tsconfig.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
{ | ||
"__comment": "AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY", | ||
"compilerOptions": { | ||
"target": "ESNext", | ||
"useDefineForClassFields": true, | ||
"lib": [ | ||
"DOM", | ||
"DOM.Iterable", | ||
"ESNext" | ||
], | ||
"allowJs": false, | ||
"skipLibCheck": true, | ||
"esModuleInterop": false, | ||
"allowSyntheticDefaultImports": true, | ||
"strict": true, | ||
"forceConsistentCasingInFileNames": true, | ||
"module": "ESNext", | ||
"moduleResolution": "Node", | ||
"resolveJsonModule": true, | ||
"isolatedModules": true, | ||
"noEmit": true, | ||
"jsx": "react-jsx", | ||
"composite": true | ||
}, | ||
"include": [ | ||
"." | ||
], | ||
"__ADD_FOR_LOCAL_DEV_references": [ | ||
{ | ||
"path": "../../../packages/core/" | ||
}, | ||
{ | ||
"path": "../../../packages/react/" | ||
} | ||
] | ||
} |
32 changes: 32 additions & 0 deletions
32
examples/02-backend/04-rendering-static-documents/vite.config.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// AUTO-GENERATED FILE, DO NOT EDIT DIRECTLY | ||
import react from "@vitejs/plugin-react"; | ||
import * as fs from "fs"; | ||
import * as path from "path"; | ||
import { defineConfig } from "vite"; | ||
// import eslintPlugin from "vite-plugin-eslint"; | ||
// https://vitejs.dev/config/ | ||
export default defineConfig((conf) => ({ | ||
plugins: [react()], | ||
optimizeDeps: {}, | ||
build: { | ||
sourcemap: true, | ||
}, | ||
resolve: { | ||
alias: | ||
conf.command === "build" || | ||
!fs.existsSync(path.resolve(__dirname, "../../packages/core/src")) | ||
? {} | ||
: ({ | ||
// Comment out the lines below to load a built version of blocknote | ||
// or, keep as is to load live from sources with live reload working | ||
"@blocknote/core": path.resolve( | ||
__dirname, | ||
"../../packages/core/src/" | ||
), | ||
"@blocknote/react": path.resolve( | ||
__dirname, | ||
"../../packages/react/src/" | ||
), | ||
} as any), | ||
}, | ||
})); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.