diff --git a/packages/theme/src/cli/utilities/theme-environment/hot-reload/error-page.test.ts b/packages/theme/src/cli/utilities/theme-environment/hot-reload/error-page.test.ts
new file mode 100644
index 00000000000..9f1aacd7a7b
--- /dev/null
+++ b/packages/theme/src/cli/utilities/theme-environment/hot-reload/error-page.test.ts
@@ -0,0 +1,46 @@
+import {getErrorPage} from './error-page.js'
+import {describe, expect, test} from 'vitest'
+
+describe('getErrorPage', () => {
+ test('renders the title and header', () => {
+ const page = getErrorPage({title: 'Failed to render', header: 'Liquid syntax error', errors: []})
+
+ expect(page).toContain('
Failed to render')
+ expect(page).toContain('Liquid syntax error')
+ })
+
+ test('renders the message and code of every error', () => {
+ const page = getErrorPage({
+ title: 'Failed to render',
+ header: 'Liquid syntax error',
+ errors: [
+ {message: 'Unknown tag', code: 'sections/header.liquid:12'},
+ {message: 'Unclosed block', code: 'sections/footer.liquid:3'},
+ ],
+ })
+
+ expect(page).toContain('Unknown tag')
+ expect(page).toContain('sections/header.liquid:12')
+ expect(page).toContain('Unclosed block')
+ expect(page).toContain('sections/footer.liquid:3')
+ })
+
+ test('escapes HTML in error messages and codes so untrusted content cannot inject markup', () => {
+ const page = getErrorPage({
+ title: 'Failed to render',
+ header: 'Liquid syntax error',
+ errors: [{message: '', code: "it's here & broken"}],
+ })
+
+ expect(page).not.toContain('