diff --git a/panel/models/reactive_html.ts b/panel/models/reactive_html.ts index c87bddd4bd..c328f120ba 100644 --- a/panel/models/reactive_html.ts +++ b/panel/models/reactive_html.ts @@ -300,7 +300,7 @@ export class ReactiveHTMLView extends HTMLBoxView { } private _render_html(literal: any, state: any={}): any { - let htm = literal + let htm = literal.replace(/[`]/g, '\\$&'); let callbacks = '' const methods: string[] = [] for (const elname in this.model.callbacks) { diff --git a/panel/tests/ui/test_reactive.py b/panel/tests/ui/test_reactive.py index c0f4a79c4b..80d9352b2e 100644 --- a/panel/tests/ui/test_reactive.py +++ b/panel/tests/ui/test_reactive.py @@ -26,6 +26,14 @@ class ReactiveComponent(ReactiveHTML): 'click': 'data.count += 1; reactive.innerText = `${data.count}`;' } +class ReactiveLiteral(ReactiveHTML): + + value = param.String() + + _template = """ +
{{value}}
+ """ + def test_reactive_html_click_js_event(page, port): component = ReactiveComponent() @@ -104,3 +112,14 @@ def test_reactive_html_set_background_no_rerender(page, port): component.styles = dict(background='green') time.sleep(0.1) expect(page.locator(".reactive")).to_have_text('1') + +def test_reactive_literal_backtick(page, port): + component = ReactiveLiteral(value="Backtick: `") + + serve(component, port=port, threaded=True, show=False) + + time.sleep(0.2) + + page.goto(f"http://localhost:{port}") + + expect(page.locator(".reactive")).to_have_text('Backtick: `')