From ab7f632cd68c9069d32d094f0312241913a5ac95 Mon Sep 17 00:00:00 2001 From: cfngc4594 Date: Sat, 22 Feb 2025 11:22:47 +0800 Subject: [PATCH] docs: add LSP integration guide for Next.js with @monaco-editor/react --- README.md | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/README.md b/README.md index 6e476be1..229c23e7 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ The examples not requiring a backend are now available [via GitHub Pages](https: - [Bad Polyfills](#bad-polyfills) - [buffer](#buffer) - [monaco-editor and react](#monaco-editor-and-react) + - [nextjs](#nextjs) - [Licenses](#licenses) ## Changelogs, project history and compatibility @@ -330,6 +331,146 @@ import { loader } from "@monaco-editor/react"; loader.config({ monaco }); ``` +#### nextjs + +This guide demonstrates how to integrate Language Server Protocol (LSP) functionality with `@monaco-editor/react` in Next.js while avoiding Server-Side Rendering (SSR) issues. + +##### Installation & Setup + +1. **Create Next.js App** + ```bash + bunx create-next-app@latest demo # or equivalent with npm/yarn/pnpm + cd demo + ``` + +2. **Install Dependencies** + Install the required packages with version constraints: + ```bash + bun add @monaco-editor/react monaco-editor@0.36.1 monaco-languageclient@5.0.1 vscode-ws-jsonrpc vscode-languageclient + bun add -D @types/vscode + ``` + > ⚠️ Version Compatibility: + > - `monaco-editor` ≤ 0.36.1 + > - `monaco-languageclient` ≤ 5.0.1 + > - If you prefer not to use the versions specified above, verify version mappings in the [Codingame/Monaco-VSCode API Compatibility Table](https://github.com/TypeFox/monaco-languageclient/blob/main/docs/versions-and-history.md#monaco-editor--codingamemonaco-vscode-api-compatibility-table) + +3. **Start a Language Server** + This guide assumes a C language server running on port `4594`. For a complete setup and configuration reference, check out this [template repository](https://github.com/cfngc4594/monaco-editor-lsp-next) + +##### Implementation + +Replace `src/app/page.tsx` with: + +```typescript +"use client"; + +import { + toSocket, + WebSocketMessageReader, + WebSocketMessageWriter, +} from "vscode-ws-jsonrpc"; +import { useEffect } from "react"; +import dynamic from "next/dynamic"; + +// Lazy-load Monaco Editor with SSR disabled +const Editor = dynamic( + async () => { + await import("vscode"); // Load VSCode type definitions + + const monaco = await import("monaco-editor"); + const { loader } = await import("@monaco-editor/react"); + loader.config({ monaco }); + + return (await import("@monaco-editor/react")).Editor; + }, + { ssr: false, loading: () =>
Loading editor...
} +); + +export default function Home() { + useEffect(() => { + const url = "ws://localhost:4594/clangd"; + const webSocket = new WebSocket(url); + + webSocket.onopen = async () => { + const socket = toSocket(webSocket); + const reader = new WebSocketMessageReader(socket); + const writer = new WebSocketMessageWriter(socket); + + const { MonacoLanguageClient } = await import("monaco-languageclient"); + const { ErrorAction, CloseAction } = await import( + "vscode-languageclient" + ); + + // Initialize language client + const languageClient = new MonacoLanguageClient({ + name: "C Language Client", + clientOptions: { + documentSelector: ["c"], + errorHandler: { + error: () => ({ action: ErrorAction.Continue }), + closed: () => ({ action: CloseAction.DoNotRestart }), + }, + }, + connectionProvider: { + get: () => Promise.resolve({ reader, writer }), + }, + }); + + languageClient.start(); + reader.onClose(() => languageClient.stop()); + }; + + webSocket.onerror = (event) => { + console.error("WebSocket error observed:", event); + }; + + webSocket.onclose = (event) => { + console.log("WebSocket closed:", event); + }; + + return () => { + webSocket.close(); + }; + }, []); + + return ( +
+ { + markers.forEach((marker) => + console.log("onValidate:", marker.message) + ); + }} + options={{ automaticLayout: true }} + loading={
Loading editor...
} + /> +
+ ); +} +``` + +##### Verification + +After running the application, check your browser console. If you see the following message: +`onValidate: Included header stdio.h is not used directly (fix available)` + +🎉 **Congratulations!** This indicates successful integration and working LSP functionality. + +##### Troubleshooting + +If the implementation doesn't work as expected: +1. Double-check the WebSocket connection and LSP server status +2. Verify all dependency versions match the compatibility table +3. Review the console for any error messages + +🔧 **Reference Implementation** +For a working example and additional configuration details, refer to this comprehensive template: +[monaco-editor-lsp-next Template](https://github.com/cfngc4594/monaco-editor-lsp-next) + ## Licenses - monaco-languageclient: [MIT](https://github.com/TypeFox/monaco-languageclient/blob/main/packages/client/LICENSE)