I’m building a Chrome extension that adds extra features to Twitch chat functionality. I’m running into an issue where programmatically setting textarea values doesn’t work as expected.
When I use JavaScript to modify the chat input field’s value and then the user submits the message (either by pressing Enter or clicking the Send button), only the original user-typed text gets sent instead of my modified value.
For instance, if a user types “Crypto” and my code changes it to “Cryptocurrency”, when they submit the message, only “Crypto” appears in the actual chat.
Additionally, whenever the user interacts with the textarea (clicking or hovering), my programmatically set value gets reverted back to what they originally typed.
It seems like Twitch maintains some internal state that tracks the actual user input and overrides my changes. How can I work around this behavior to make my extension function properly?
twitch chat’s a pain for extensions since they use custom stuff. don’t bother fighting react’s state management - just intercept the submit event instead. listen for enter key presses or send button clicks, then preventDefault() and manually hit the chat api with your modified text. this skips the whole textarea validation mess and works way better than trying to sync with react’s internal state.
I’ve run into this exact issue building streaming platform extensions. Twitch uses controlled React components where the displayed value is tied to state, not the actual DOM value. Your selector targeting nested child nodes will break every time Twitch updates their UI.
What fixed it for me: simulate real user input instead of just setting values. Use KeyboardEvent constructor to dispatch keydown/keyup events for each character, or try document.execCommand('insertText', false, 'your text') if you can get proper focus. You can also clear existing content with selectAll first, then insert your text.
Timing matters here - use a MutationObserver to watch for when the textarea gets focus, then immediately apply your changes. React reconciles DOM state when users interact with inputs, so you need to beat that timing.
This happens because Twitch runs on React, and React keeps its own virtual DOM state that fights with direct DOM changes. When you modify the textarea value directly, React’s internal state doesn’t know about it, so it just reverts your changes on the next render. I’ve hit the same problem with React chat systems. You can’t just set the value property - you need to trigger React’s synthetic events too. Dispatch input and change events after you modify the value: const input = document.querySelector(‘.chat-input__textarea’).firstChild.childNodes[0]; input.value = “Cryptocurrency”; input.dispatchEvent(new Event(‘input’, { bubbles: true })); input.dispatchEvent(new Event(‘change’, { bubbles: true })); This makes React recognize the change and update its internal state. Just heads up though - Twitch updates their DOM structure pretty regularly, so your selector might break later. You’ll want more robust selectors or some way to monitor DOM changes.
I’ve hit this exact issue with Twitch extensions. The problem is how they handle events - that textarea has listeners that grab the original input before form submission and store it separately from what you see in the DOM. Don’t mess with the textarea directly. Instead, hook into the message submission flow earlier. Watch for form submission events on the chat container, then intercept and modify the message payload before it hits Twitch’s servers. Use addEventListener('submit', callback, true) with capture mode to catch it early. What worked for me was watching for the CSS classes that show up when users start typing, then immediately replacing their input with setSelectionRange() plus insertText. This keeps the natural user flow intact while making sure your changes actually stick through submission. The trick is making your changes look like real user input instead of DOM manipulation.