MM-69751 Replace concurrent React user setting with feature flag and add to root.html (#37422)

* MM-69751 Replace concurrent React user setting with feature flag and add to root.html

* Address Coderabbit feedback
This commit is contained in:
Harrison Healey
2026-07-14 14:25:15 -04:00
committed by GitHub
parent b959e88bf6
commit d3ebd0ff65
12 changed files with 174 additions and 229 deletions
+60 -17
View File
@@ -12,6 +12,7 @@ import (
"path"
"path/filepath"
"regexp"
"strconv"
"strings"
"github.com/pkg/errors"
@@ -23,8 +24,8 @@ import (
// getSubpathScript renders the inline script that defines window.publicPath to change how webpack loads assets.
func getSubpathScript(subpath string) string {
if subpath == "" {
subpath = "/"
if subpath == "" || subpath == "/" {
return ""
}
newPath := path.Join(subpath, "static") + "/"
@@ -32,21 +33,42 @@ func getSubpathScript(subpath string) string {
return fmt.Sprintf("window.publicPath='%s'", newPath)
}
// GetSubpathScriptHash computes the script-src addition required for the subpath script to bypass CSP protections.
func GetSubpathScriptHash(subpath string) string {
// No hash is required for the default subpath.
if subpath == "" || subpath == "/" {
// getConcurrentReactScript renders the inline script that defines window.enableConcurrentReact to change how React
// initializes the web app.
func getConcurrentReactScript(enableConcurrentReact bool) string {
if !enableConcurrentReact {
return ""
}
scriptHash := sha256.Sum256([]byte(getSubpathScript(subpath)))
return "window.enableConcurrentReact=true"
}
// GetScriptHash computes the script-src addition required for an inline script injected into the root.html.
func GetScriptHash(script string) string {
// No hash is required when there's no script
if script == "" {
return ""
}
scriptHash := sha256.Sum256([]byte(script))
return fmt.Sprintf(" 'sha256-%s'", base64.StdEncoding.EncodeToString(scriptHash[:]))
}
// UpdateAssetsSubpathInDir rewrites assets in the given directory to assume the application is
// hosted at the given subpath instead of at the root. No changes are written unless necessary.
func UpdateAssetsSubpathInDir(subpath, directory string) error {
// GetStaticScriptHashes computes the combined script-src additions required for the inline scripts injected
// into root.html to bypass CSP protections.
func GetStaticScriptHashes(subpath string, enableConcurrentReact bool) string {
return GetScriptHash(getSubpathScript(subpath)) + GetScriptHash(getConcurrentReactScript(enableConcurrentReact))
}
// UpdateAssetsSubpathInDir rewrites static assets in the given directory based on configuration options.
// The following changes are made:
// - HTML and CSS files are rewritten to assume the application is hosted at the given subpath instead of at the root.
// - HTML is rewritten to add the enableConcurrentReact setting, needed while loading the web app. If omitted, the
// existing value is preserved.
//
// No changes are written unless necessary.
func UpdateAssetsSubpathInDir(subpath, directory string, enableConcurrentReactPtr *bool) error {
if subpath == "" {
subpath = "/"
}
@@ -82,8 +104,21 @@ func UpdateAssetsSubpathInDir(subpath, directory string) error {
pathToReplace := path.Join(oldSubpath, "static") + "/"
newPath := path.Join(subpath, "static") + "/"
// Keep the previous value of enableConcurrentReact if it isn't provided
enableConcurrentReact := false
if enableConcurrentReactPtr == nil {
reConcurrentReactScript := regexp.MustCompile("window.enableConcurrentReact=(true|false)")
if matches := reConcurrentReactScript.FindSubmatch(oldRootHTML); matches != nil {
if value, convErr := strconv.ParseBool(string(matches[1])); convErr == nil {
enableConcurrentReact = value
}
}
} else {
enableConcurrentReact = *enableConcurrentReactPtr
}
// Update the root.html file
if err := updateRootFile(string(oldRootHTML), rootHTMLPath, alreadyRewritten, pathToReplace, newPath, subpath); err != nil {
if err := updateRootFile(string(oldRootHTML), rootHTMLPath, alreadyRewritten, pathToReplace, newPath, subpath, enableConcurrentReact); err != nil {
return fmt.Errorf("failed to update root.html: %w", err)
}
@@ -95,7 +130,7 @@ func UpdateAssetsSubpathInDir(subpath, directory string) error {
return nil
}
func updateRootFile(oldRootHTML string, rootHTMLPath string, alreadyRewritten bool, pathToReplace, newPath, subpath string) error {
func updateRootFile(oldRootHTML string, rootHTMLPath string, alreadyRewritten bool, pathToReplace, newPath, subpath string, enableConcurrentReact bool) error {
newRootHTML := oldRootHTML
reCSP := regexp.MustCompile(`<meta http-equiv="Content-Security-Policy" content="script-src 'self'([^"]*)">`)
@@ -105,7 +140,7 @@ func updateRootFile(oldRootHTML string, rootHTMLPath string, alreadyRewritten bo
newRootHTML = reCSP.ReplaceAllLiteralString(newRootHTML, fmt.Sprintf(
`<meta http-equiv="Content-Security-Policy" content="script-src 'self'%s">`,
GetSubpathScriptHash(subpath),
GetStaticScriptHashes(subpath, enableConcurrentReact),
))
// Rewrite the root.html references to `/static/*` to include the given subpath.
@@ -114,7 +149,6 @@ func updateRootFile(oldRootHTML string, rootHTMLPath string, alreadyRewritten bo
newRootHTML = strings.Replace(newRootHTML, pathToReplace, newPath, -1)
publicPathInWindowsScriptRegex := regexp.MustCompile(`(?s)<script id="publicPathInWindowScript">(.*?)</script>`)
if alreadyRewritten && subpath == "/" {
// Remove window global publicPath definition if subpath is root
newRootHTML = publicPathInWindowsScriptRegex.ReplaceAllLiteralString(newRootHTML, "<script id=\"publicPathInWindowScript\"></script>")
@@ -124,6 +158,10 @@ func updateRootFile(oldRootHTML string, rootHTMLPath string, alreadyRewritten bo
newRootHTML = publicPathInWindowsScriptRegex.ReplaceAllLiteralString(newRootHTML, fmt.Sprintf("<script id=\"publicPathInWindowScript\">%s</script>", subpathScript))
}
// Inject (or clear) the script defining `window.enableConcurrentReact` to match the feature flag.
concurrentReactScriptRegex := regexp.MustCompile(`(?s)<script id="enableConcurrentReactScript">(.*?)</script>`)
newRootHTML = concurrentReactScriptRegex.ReplaceAllLiteralString(newRootHTML, fmt.Sprintf("<script id=\"enableConcurrentReactScript\">%s</script>", getConcurrentReactScript(enableConcurrentReact)))
if newRootHTML == oldRootHTML {
mlog.Debug("No need to rewrite unmodified root.html", mlog.String("from_subpath", pathToReplace), mlog.String("to_subpath", newPath))
return nil
@@ -169,8 +207,8 @@ func updateManifestAndCSSFiles(staticDir, pathToReplace, newPath, subpath string
// UpdateAssetsSubpath rewrites assets in the /client directory to assume the application is hosted
// at the given subpath instead of at the root. No changes are written unless necessary.
func UpdateAssetsSubpath(subpath string) error {
return UpdateAssetsSubpathInDir(subpath, model.ClientDir)
func UpdateAssetsSubpath(subpath string, enableConcurrentReact *bool) error {
return UpdateAssetsSubpathInDir(subpath, model.ClientDir, enableConcurrentReact)
}
// UpdateAssetsSubpathFromConfig uses UpdateAssetsSubpath and any path defined in the SiteURL.
@@ -193,7 +231,12 @@ func UpdateAssetsSubpathFromConfig(config *model.Config) error {
return err
}
return UpdateAssetsSubpath(subpath)
enableConcurrentReact := false
if config != nil && config.FeatureFlags != nil {
enableConcurrentReact = config.FeatureFlags.EnableConcurrentReact
}
return UpdateAssetsSubpath(subpath, &enableConcurrentReact)
}
func GetSubpathFromConfig(config *model.Config) (string, error) {
+53 -2
View File
@@ -53,7 +53,7 @@ func TestUpdateAssetsSubpath(t *testing.T) {
tempDir := t.TempDir()
t.Chdir(tempDir)
err := utils.UpdateAssetsSubpath("/")
err := utils.UpdateAssetsSubpath("/", nil)
require.Error(t, err)
})
@@ -159,7 +159,7 @@ func TestUpdateAssetsSubpath(t *testing.T) {
require.NoError(t, os.WriteFile(filepath.Join(tempDir, model.ClientDir, "root.html"), []byte(testCase.RootHTML), 0700))
require.NoError(t, os.WriteFile(filepath.Join(tempDir, model.ClientDir, "main.css"), []byte(testCase.MainCSS), 0700))
require.NoError(t, os.WriteFile(filepath.Join(tempDir, model.ClientDir, "manifest.json"), []byte(testCase.ManifestJSON), 0700))
err := utils.UpdateAssetsSubpath(testCase.Subpath)
err := utils.UpdateAssetsSubpath(testCase.Subpath, nil)
if testCase.ExpectedError != nil {
require.Equal(t, testCase.ExpectedError, err)
} else {
@@ -186,6 +186,57 @@ func TestUpdateAssetsSubpath(t *testing.T) {
})
}
func TestUpdateAssetsSubpathConcurrentReact(t *testing.T) {
// concurrentReactHash is the CSP script-src addition for the "window.enableConcurrentReact=true" inline script.
const concurrentReactHash = " 'sha256-VKORZJUo6WeDwDHwpxEgzZDt8C1kBbDOmUq72sfrx8M='"
// rootHTML renders a minimal root.html with the given CSP addition and concurrent React script body.
rootHTML := func(cspExtra, concurrentReactBody string) string {
return `<!DOCTYPE html> <html lang=en> <head> ` +
`<meta http-equiv="Content-Security-Policy" content="script-src 'self'` + cspExtra + `"> ` +
`<script id="publicPathInWindowScript"></script> ` +
`<script id="enableConcurrentReactScript">` + concurrentReactBody + `</script> ` +
`<link href="/static/main.js" rel="stylesheet"></head> <body></body> </html>`
}
writeAndUpdate := func(t *testing.T, initial string, enableConcurrentReact *bool) string {
t.Helper()
tempDir := t.TempDir()
t.Chdir(tempDir)
require.NoError(t, os.Mkdir(model.ClientDir, 0700))
require.NoError(t, os.WriteFile(filepath.Join(tempDir, model.ClientDir, "root.html"), []byte(initial), 0700))
require.NoError(t, utils.UpdateAssetsSubpath("/", enableConcurrentReact))
contents, err := os.ReadFile(filepath.Join(tempDir, model.ClientDir, "root.html"))
require.NoError(t, err)
return string(contents)
}
t.Run("enabled injects the script and CSP hash", func(t *testing.T) {
got := writeAndUpdate(t, rootHTML("", ""), model.NewPointer(true))
require.Equal(t, rootHTML(concurrentReactHash, "window.enableConcurrentReact=true"), got)
})
t.Run("disabled clears the script and CSP hash", func(t *testing.T) {
got := writeAndUpdate(t, rootHTML(concurrentReactHash, "window.enableConcurrentReact=true"), model.NewPointer(false))
require.Equal(t, rootHTML("", ""), got)
})
t.Run("nil preserves an enabled script", func(t *testing.T) {
initial := rootHTML(concurrentReactHash, "window.enableConcurrentReact=true")
got := writeAndUpdate(t, initial, nil)
require.Equal(t, initial, got)
})
t.Run("nil preserves a disabled script", func(t *testing.T) {
initial := rootHTML("", "")
got := writeAndUpdate(t, initial, nil)
require.Equal(t, initial, got)
})
}
func TestGetSubpathFromConfig(t *testing.T) {
testCases := []struct {
Description string
+10 -4
View File
@@ -48,9 +48,15 @@ func (w *Web) NewHandler(h func(*Context, http.ResponseWriter, *http.Request)) h
}
func (w *Web) NewStaticHandler(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler {
// Determine the CSP SHA directive needed for subpath support, if any. This value is fixed
// on server start and intentionally requires a restart to take effect.
subpath, _ := utils.GetSubpathFromConfig(w.srv.Config())
// Determine the CSP SHA directives needed for the inline scripts injected into root.html.
// These values are fixed on server start and intentionally require a restart to take effect.
cfg := w.srv.Config()
subpath, _ := utils.GetSubpathFromConfig(cfg)
enableConcurrentReact := false
if cfg.FeatureFlags != nil {
enableConcurrentReact = cfg.FeatureFlags.EnableConcurrentReact
}
return &Handler{
Srv: w.srv,
@@ -61,7 +67,7 @@ func (w *Web) NewStaticHandler(h func(*Context, http.ResponseWriter, *http.Reque
RequireMfa: false,
IsStatic: true,
cspShaDirective: utils.GetSubpathScriptHash(subpath),
cspShaDirective: utils.GetStaticScriptHashes(subpath, enableConcurrentReact),
}
}
+36
View File
@@ -338,6 +338,42 @@ func TestHandlerServeCSPHeader(t *testing.T) {
assert.Equal(t, []string{"frame-ancestors 'self' " + *th.App.Config().ServiceSettings.FrameAncestors + "; script-src 'self'"}, response.Header()["Content-Security-Policy"])
})
t.Run("static, with EnableConcurrentReact enabled", func(t *testing.T) {
th := SetupWithStoreMock(t)
// Feature flags are read-only in the config store, so mutate the live config directly.
th.App.Config().FeatureFlags.EnableConcurrentReact = true
web := New(th.Server)
// NewStaticHandler computes the CSP SHA directive from the current config, so the
// concurrent React inline script's hash must be present in the script-src directive.
handler := web.NewStaticHandler(handlerForCSPHeader)
request := httptest.NewRequest("POST", "/", nil)
response := httptest.NewRecorder()
handler.ServeHTTP(response, request)
assert.Equal(t, 200, response.Code)
assert.Equal(t, []string{"frame-ancestors 'self' " + *th.App.Config().ServiceSettings.FrameAncestors + "; script-src 'self' 'sha256-VKORZJUo6WeDwDHwpxEgzZDt8C1kBbDOmUq72sfrx8M='"}, response.Header()["Content-Security-Policy"])
})
t.Run("static, with EnableConcurrentReact disabled", func(t *testing.T) {
th := SetupWithStoreMock(t)
// Feature flags are read-only in the config store, so mutate the live config directly.
th.App.Config().FeatureFlags.EnableConcurrentReact = false
web := New(th.Server)
handler := web.NewStaticHandler(handlerForCSPHeader)
request := httptest.NewRequest("POST", "/", nil)
response := httptest.NewRecorder()
handler.ServeHTTP(response, request)
assert.Equal(t, 200, response.Code)
assert.Equal(t, []string{"frame-ancestors 'self' " + *th.App.Config().ServiceSettings.FrameAncestors + "; script-src 'self'"}, response.Header()["Content-Security-Policy"])
})
t.Run("static, with subpath and frame ancestors", func(t *testing.T) {
th := SetupWithStoreMock(t)
+1 -1
View File
@@ -554,7 +554,7 @@ func configSubpathCmdF(cmd *cobra.Command, _ []string) error {
assetsDir, _ := cmd.Flags().GetString("assets-dir")
path, _ := cmd.Flags().GetString("path")
if err := utils.UpdateAssetsSubpathInDir(path, assetsDir); err != nil {
if err := utils.UpdateAssetsSubpathInDir(path, assetsDir, nil); err != nil {
return errors.Wrap(err, "failed to update assets subpath")
}
+5
View File
@@ -138,6 +138,9 @@ type FeatureFlags struct {
ClusterGracefulDrain bool
ChannelBookmarks bool
// Enable React concurrent rendering
EnableConcurrentReact bool
}
func (f *FeatureFlags) SetDefaults() {
@@ -196,6 +199,8 @@ func (f *FeatureFlags) SetDefaults() {
f.MmBlocksEnabled = true
f.ChannelBookmarks = true
f.EnableConcurrentReact = false
}
// IsChannelPermissionPoliciesEnabled reports whether channel-scope
@@ -160,12 +160,12 @@ export function handleLoginLogoutSignal(e: StorageEvent): ThunkActionFunc<void>
export function logIfConcurrentReactEnabled(): ActionFuncAsync<boolean> {
return async () => {
const concurrentReactEnabled = localStorage.getItem('enable_concurrent_react_experimental') === 'true';
const concurrentReactEnabled = window.enableConcurrentReact;
if (concurrentReactEnabled) {
Client4.logClientError(
"This user's session is using experimental concurrent React which may cause visual bugs. It can be " +
'disabled from Settings > Advanced or by clearing their browser storage.',
"This user's session is using experimental concurrent React which may cause visual bugs. It is enabled " +
'for all users due to a feature flag.',
LogLevel.Debug,
);
}
@@ -1,184 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useState} from 'react';
import {FormattedMessage} from 'react-intl';
import {useSelector} from 'react-redux';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
import useDidUpdate from 'components/common/hooks/useDidUpdate';
import SettingItemMax from 'components/setting_item_max';
import SettingItemMin from 'components/setting_item_min';
import {a11yFocus} from 'utils/utils';
import type {GlobalState} from 'types/store';
const section = 'concurrentReactExperimental';
const storageKey = 'enable_concurrent_react_experimental';
type Props = {
activeSection: string;
adminMode?: boolean;
onUpdateSection: (section?: string) => void;
renderOnOffLabel: (enabled: string) => React.JSX.Element;
};
export default function EnableConcurrentReactExperimentalSection({
activeSection,
adminMode,
onUpdateSection,
renderOnOffLabel,
}: Props) {
const enableDeveloperMode = useSelector((state: GlobalState) => getConfig(state).EnableDeveloper === 'true');
const currentValue = useLocalStorageItem(storageKey, 'false');
const [enabled, setEnabled] = useState(currentValue);
const active = activeSection === section;
const [prevActive, setPrevActive] = useState(active);
if (active !== prevActive) {
setPrevActive(active);
setEnabled(currentValue);
}
const minRef = React.createRef<SettingItemMin>();
useDidUpdate(() => {
if (!active) {
minRef.current?.focus();
}
}, [active]);
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
setEnabled(e.currentTarget.value);
a11yFocus(e.currentTarget);
}, []);
const handleSubmit = useCallback(() => {
localStorage.setItem(storageKey, enabled);
// Manually dispatch an event to update currentvalue because storage events are only fired for other tabs
requestAnimationFrame(() => {
window.dispatchEvent(new StorageEvent('storage', {
key: storageKey,
newValue: enabled,
storageArea: localStorage,
}));
onUpdateSection();
});
}, [enabled, onUpdateSection]);
if (adminMode || !enableDeveloperMode) {
return null;
}
if (!active) {
return (
<SettingItemMin
ref={minRef}
title={
<FormattedMessage
id='user.settings.advance.concurrentReactExperimental'
defaultMessage='Enable Concurrent React (Experimental)'
/>
}
describe={renderOnOffLabel(currentValue)}
section={section}
updateSection={onUpdateSection}
/>
);
}
return (
<SettingItemMax
title={
<FormattedMessage
id='user.settings.advance.concurrentReactExperimental'
defaultMessage='Enable Concurrent React (Experimental)'
/>
}
inputs={[
<fieldset key='joinLeaveSetting'>
<legend className='form-legend hidden-label'>
<FormattedMessage
id='user.settings.advance.concurrentReactExperimental'
defaultMessage='Enable Concurrent React (Experimental)'
/>
</legend>
<div className='radio'>
<label>
<input
id='joinLeaveOn'
type='radio'
value={'true'}
name={section}
checked={enabled === 'true'}
onChange={handleChange}
/>
<FormattedMessage
id='user.settings.advance.on'
defaultMessage='On'
/>
</label>
<br/>
</div>
<div className='radio'>
<label>
<input
id='joinLeaveOff'
type='radio'
value={'false'}
name={section}
checked={enabled === 'false'}
onChange={handleChange}
/>
<FormattedMessage
id='user.settings.advance.off'
defaultMessage='Off'
/>
</label>
<br/>
</div>
<div className='mt-5'>
<FormattedMessage
id='user.settings.advance.concurrentReactExperimentalDesc1'
defaultMessage={'When "On", enable concurrent React support for development. This is known to cause issues and should only be done if you know what you\'re doing.'}
tagName='p'
/>
<FormattedMessage
id='user.settings.advance.concurrentReactExperimentalDesc2'
defaultMessage={'You may need to refresh the page before this setting takes effect.'}
tagName='p'
/>
</div>
</fieldset>,
]}
submit={handleSubmit}
saving={false}
updateSection={onUpdateSection}
/>
);
}
function useLocalStorageItem(key: string, defaultValue: string) {
const [value, setValue] = useState(() => (localStorage.getItem(key) || defaultValue));
useEffect(() => {
const handleStorageEvent = (e: StorageEvent) => {
if (e.key === key && e.storageArea === localStorage) {
setValue(e.newValue || defaultValue);
}
};
window.addEventListener('storage', handleStorageEvent);
return () => {
window.removeEventListener('storage', handleStorageEvent);
};
}, [key, defaultValue]);
return value;
}
@@ -1,8 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
/* eslint-disable max-lines */
import React from 'react';
import type {ReactNode} from 'react';
import {FormattedMessage, defineMessages} from 'react-intl';
@@ -20,7 +18,6 @@ import SettingItemMax from 'components/setting_item_max';
import Constants, {AdvancedSections, Preferences} from 'utils/constants';
import {a11yFocus} from 'utils/utils';
import EnableConcurrentReactExperimentalSection from './enable_concurrent_react_experimental_section';
import JoinLeaveSection from './join_leave_section';
import PerformanceDebuggingSection from './performance_debugging_section';
import WysiwygEditorSection from './wysiwyg_editor_section';
@@ -796,13 +793,6 @@ export default class AdvancedSettingsDisplay extends React.PureComponent<Props,
{syncDraftsSectionDivider}
{syncDraftsSection}
{formattingSectionDivider}
<EnableConcurrentReactExperimentalSection
activeSection={this.props.activeSection}
onUpdateSection={this.handleUpdateSection}
adminMode={this.props.adminMode}
renderOnOffLabel={this.renderOnOffLabel}
/>
<div className='divider-light'/>
{deactivateAccountSection}
<div className='divider-dark'/>
{makeConfirmationModal}
+3 -5
View File
@@ -24,6 +24,7 @@ import '@mattermost/components/dist/index.esm.css';
declare global {
interface Window {
publicPath?: string;
enableConcurrentReact?: boolean;
}
}
@@ -56,12 +57,9 @@ function preRenderSetup(onPreRenderSetupReady: () => void) {
function renderReactRootComponent() {
const container = document.getElementById('root')!;
if (localStorage.getItem('enable_concurrent_react_experimental') === 'true') {
if (window.enableConcurrentReact) {
// eslint-disable-next-line no-console
console.log(
'Enabling concurrent React 18. To disable this, go to Settings > Advanced > Enable Concurrent React ' +
'(Experimental) or clear your browser storage.',
);
console.log('Enabling concurrent React 18 due to server-wide feature flag');
// Enable this experimentally since it may cause other issues
ReactDOMClient.createRoot(container).render(<App/>);
-3
View File
@@ -7198,9 +7198,6 @@
"user_settings.notifications.test_notification.send_button.sending": "Sending a test notification",
"user_settings.notifications.test_notification.send_button.sent": "Test notification sent",
"user_settings.notifications.test_notification.title": "Troubleshooting notifications",
"user.settings.advance.concurrentReactExperimental": "Enable Concurrent React (Experimental)",
"user.settings.advance.concurrentReactExperimentalDesc1": "When \"On\", enable concurrent React support for development. This is known to cause issues and should only be done if you know what you're doing.",
"user.settings.advance.concurrentReactExperimentalDesc2": "You may need to refresh the page before this setting takes effect.",
"user.settings.advance.confirmDeactivateAccountTitle": "Confirm Deactivation",
"user.settings.advance.confirmDeactivateDesc": "Are you sure you want to deactivate your account? This can only be reversed by your System Administrator.",
"user.settings.advance.deactivate_member_modal.deactivateButton": "Yes, deactivate my account",
+3
View File
@@ -22,6 +22,9 @@
<!-- Initialize subpath empty script for subpath support which will be replaced by server/channels/utils/subpath.go -->
<script id="publicPathInWindowScript"></script>
<!-- Initialize empty script for the EnableConcurrentReact feature flag which will be replaced by server/channels/utils/subpath.go -->
<script id="enableConcurrentReactScript"></script>
<!--
This "empty" link element is used as a dynamic inject placeholder for the syntax highlighting css styles:
1. The highlight.js lib finds this element by its 'code_theme' class.