The component I wrote is as follows.This Blazor component integrates CKEditor into a Blazor project using JavaScript interop (IJSRuntime).A simple element is defined with an id that defaults to "editor", but the EditorId can be passed as a parameter to allow multiple CKEditor instances.Value: The current value of the editor, bound to the content in CKEditor.ValueChanged: An EventCallback that notifies the parent component of content changes in CKEditor.EditorId: The id of the editor, which defaults to "editor", used for JavaScript interop to link CKEditor to the right element.
@using Microsoft.JSInterop<textarea id="@EditorId"></textarea>@code { [Inject] private IJSRuntime JS { get; set; } [Parameter] public string Value { get; set; } [Parameter] public EventCallback<string> ValueChanged { get; set; } [Parameter] public string EditorId { get; set; } = "editor"; private DotNetObjectReference<CkEditor> _objRef; protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { _objRef = DotNetObjectReference.Create(this); await JS.InvokeVoidAsync("initializeCkEditor", EditorId, _objRef); } } [JSInvokable] public async Task UpdateValue() { var content = await JS.InvokeAsync<string>("getEditorContent", EditorId); if (content != Value) { Value = content; await ValueChanged.InvokeAsync(Value); } } public void Dispose() { _objRef?.Dispose(); }}Also, the javascript code is according to the following code
window.initializeCkEditor = (editorId, dotNetObject) => { if (CKEDITOR.instances[editorId]) { CKEDITOR.instances[editorId].destroy(); } CKEDITOR.replace(editorId); CKEDITOR.instances[editorId].on('change', function () { dotNetObject.invokeMethodAsync('UpdateValue'); });};window.getEditorContent = (editorId) => { if (CKEDITOR.instances[editorId]) { return CKEDITOR.instances[editorId].getData(); } return '';};window.setEditorContent = (editorId, content) => { const interval = setInterval(() => { if (CKEDITOR.instances[editorId]) { CKEDITOR.instances[editorId].setData(content); clearInterval(interval); } }, 100); };Sometimes when loading the component page it doesn't work properly.