Skip to content

Comments

Add preview vite configuration.#650

Draft
Mati365 wants to merge 2 commits intomasterfrom
ck/add-preview-option
Draft

Add preview vite configuration.#650
Mati365 wants to merge 2 commits intomasterfrom
ck/add-preview-option

Conversation

@Mati365
Copy link
Member

@Mati365 Mati365 commented Feb 19, 2026

🚀 Summary

Add preview vite configuration. It allows to access built js files through http://localhost:8080/index.js. It's useful for testing react integration in manual tests.


📌 Related issues

@Mati365
Copy link
Member Author

Mati365 commented Feb 19, 2026

If you use the snippets provided below, you can use the local React integration with the current editor build from manual tests. This way, you don't need to build the entire CKEditor 5 project.

<head>
	<meta
		http-equiv="Content-Security-Policy"
		content="default-src * 'unsafe-inline' 'unsafe-eval' data: blob:; script-src * 'unsafe-inline' 'unsafe-eval' data: blob:; style-src * 'unsafe-inline' data: blob:; img-src * data: blob:; connect-src *; font-src * data:; frame-src *;">

	<script type="importmap">
		{
			"imports": {
				"react": "https://esm.sh/react@19",
				"react-dom/client": "https://esm.sh/react-dom@19/client",
				"@ckeditor/ckeditor5-integrations-common": "https://esm.sh/@ckeditor/ckeditor5-integrations-common",
				"ckeditor5-react": "http://localhost:8080/index.js"
			}
		}
	</script>
	<script>
		window.React = import( 'react' );
		window.ReactDOMClient = import( 'react-dom/client' );
		window.CKEditor5React = import( 'ckeditor5-react' );
	</script>
</head>

<div id="react-root"></div>
/**
 * @license Copyright (c) 2003-2026, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-licensing-options
 */

import { ClassicEditor } from '@ckeditor/ckeditor5-editor-classic';
import { MultiRootEditor } from '@ckeditor/ckeditor5-editor-multi-root';
import { Enter } from '@ckeditor/ckeditor5-enter';
import { Typing } from '@ckeditor/ckeditor5-typing';
import { Link } from '../../src/link.js';
import { Paragraph } from '@ckeditor/ckeditor5-paragraph';
import { Undo } from '@ckeditor/ckeditor5-undo';
import { Bold, Italic } from '@ckeditor/ckeditor5-basic-styles';
import CKEditorInspector from '@ckeditor/ckeditor5-inspector';

const [ React, ReactDOM, CKEditor5React ] = await Promise.all( [
	window.React,
	window.ReactDOMClient,
	window.CKEditor5React
] );

const { CKEditor, useMultiRootEditor } = CKEditor5React;
const { createElement: jsx } = React;

const CKEditor5Demo = () => {
	return jsx( 'div', null,
		jsx( 'h3', null, 'CKEditor5 Classic Demo' ),
		jsx( CKEditor, {
			editor: ClassicEditor,
			config: {
				plugins: [ Link, Bold, Italic, Typing, Paragraph, Undo, Enter ],
				toolbar: [ 'link', 'bold', 'italic', '|', 'undo', 'redo' ]
			},
			onReady: editor => {
				CKEditorInspector.attach( { Classic: editor } );
			}
		} )
	);
};

const MultiRootDemo = () => {
	const { toolbarElement, editableElements, setData, setAttributes } = useMultiRootEditor( {
		editor: MultiRootEditor,
		config: {
			plugins: [ Link, Bold, Italic, Typing, Paragraph, Undo, Enter ],
			toolbar: [ 'link', 'bold', 'italic', '|', 'undo', 'redo' ]
		},
		data: {
			header: '<p>Document header</p>',
			content: '<p>Main content</p>'
		},
		onReady: editor => {
			CKEditorInspector.attach( { Multiroot: editor } );
		}
	} );

	const addRoot = () => {
		const id = `root_${ Date.now() }`;

		setData( prevData => ( {
			...prevData,
			[ id ]: `<p>New area: ${ id }</p>`
		} ) );

		setAttributes( prevAttributes => ( {
			...prevAttributes,
			[ id ]: {}
		} ) );
	};

	const removeRoot = id => {
		setData( prevData => {
			// eslint-disable-next-line no-unused-vars
			const { [ id ]: _removed, ...rest } = prevData;

			return rest;
		} );
	};

	const editables = editableElements.map( element => {
		const id = element.props.rootName;

		return jsx( 'div', { key: id, style: { marginBottom: '20px', padding: '10px', border: '1px solid #ddd' } },
			jsx( 'div', { style: { display: 'flex', justifyContent: 'space-between', marginBottom: '10px' } },
				jsx( 'strong', null, `Root name: ${ id }` ),
				jsx( 'button', { onClick: () => removeRoot( id ) }, 'Remove this root' )
			),
			element
		);
	} );

	return jsx( 'div', null,
		jsx( 'h3', null, 'CKEditor5 Multi-root Demo' ),
		jsx( 'button', { onClick: addRoot, style: { marginBottom: '20px', padding: '5px 10px' } }, '+ Add new root' ),
		jsx( 'div', { style: { marginBottom: '20px', padding: '10px', background: '#f5f5f5', border: '1px solid #ccc' } },
			toolbarElement
		),
		jsx( 'div', null, editables )
	);
};

const App = () => {
	return jsx( 'div', null,
		jsx( CKEditor5Demo, null ),
		jsx( 'hr', { style: { margin: '40px 0' } } ),
		jsx( MultiRootDemo, null )
	);
};

const rootElement = document.getElementById( 'react-root' );
const root = ReactDOM.createRoot( rootElement );

root.render( jsx( App ) );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant