Limitations
-
Read this article: Supported Web Features
-
WebKit version is
615.1.18.100.1. -
Supports ES2022 and below JavaScript features.
-
Videois not supported. UseGIFimages instead. -
Audiois not supported. Play sounds from SKSE. -
WebGLis not supported. -
UI refresh rate has 60 FPS cap for now.
-
CPU rendering is only available for now.
-
If you use TailwindCSS in your UI then use v3.
-
Avoid using heavy CSS operations like shadows/filters/gradients/blur in large amount for now. CPU rendering struggles with these, leading to potential FPS drops. We plan to add GPU rendering in the future.
-
JS event
contextmenudoesn’t work. Use this implementation instead:window.addEventListener('mousedown', function (event) {if (event.button === 2) {// right-clickconst contextMenuEvent = new MouseEvent('contextmenu', {...event,view: window,bubbles: true,cancelable: true,screenX: event.pageX,screenY: event.pageY,clientX: event.pageX,clientY: event.pageY,});event.target?.dispatchEvent(contextMenuEvent);}}); -
Blocking specific keys from input: To prevent certain keys (e.g., numpad keys) from adding content to focused inputs, you need to use a combination of
keydownandbeforeinputevent listeners:React Example:
import { useEffect } from 'react';// Define keys you want to block (e.g., numpad keys)const blockedKeys = [{ keyCode: 96 }, // Numpad 0{ keyCode: 97 }, // Numpad 1{ keyCode: 98 }, // Numpad 2{ keyCode: 99 }, // Numpad 3{ keyCode: 100 }, // Numpad 4{ keyCode: 101 }, // Numpad 5{ keyCode: 102 }, // Numpad 6{ keyCode: 103 }, // Numpad 7{ keyCode: 104 }, // Numpad 8{ keyCode: 105 }, // Numpad 9];function MyComponent() {useEffect(() => {let lastKey: null | number = null;const handleKeyDown = (event: KeyboardEvent) => {lastKey = event.keyCode;};const handleBeforeInput = (event: InputEvent) => {if (lastKey !== null && blockedKeys.some(k => k.keyCode === lastKey)) {console.log("Blocked input:", { data: event.data, lastKey });event.preventDefault();}};window.addEventListener("keydown", handleKeyDown, { capture: true });window.addEventListener("beforeinput", handleBeforeInput, { capture: true });return () => {window.removeEventListener("keydown", handleKeyDown, { capture: true });window.removeEventListener("beforeinput", handleBeforeInput, { capture: true });};}, []);return <input type="text" placeholder="Type here..." />;}Vanilla JavaScript Example:
// Define keys you want to block (e.g., numpad keys)const blockedKeys = [{ keyCode: 96 }, // Numpad 0{ keyCode: 97 }, // Numpad 1{ keyCode: 98 }, // Numpad 2{ keyCode: 99 }, // Numpad 3{ keyCode: 100 }, // Numpad 4{ keyCode: 101 }, // Numpad 5{ keyCode: 102 }, // Numpad 6{ keyCode: 103 }, // Numpad 7{ keyCode: 104 }, // Numpad 8{ keyCode: 105 }, // Numpad 9];let lastKey = null;function handleKeyDown(event) {lastKey = event.keyCode;}function handleBeforeInput(event) {if (lastKey !== null && blockedKeys.some(k => k.keyCode === lastKey)) {console.log("Blocked input:", { data: event.data, lastKey });event.preventDefault();}}// Add event listenerswindow.addEventListener("keydown", handleKeyDown, { capture: true });window.addEventListener("beforeinput", handleBeforeInput, { capture: true });// Don't forget to cleanup when needed// window.removeEventListener("keydown", handleKeyDown, { capture: true });// window.removeEventListener("beforeinput", handleBeforeInput, { capture: true });