← back to NationalPaperHangers
JSON-serialise booking-page analytics values so a stray quote or newline cannot break the script
098e20c4077b47149565887551e425870b78fc9a · 2026-05-19 08:03:55 -0700 · Steve
Files touched
M views/public/booking.ejs
Diff
commit 098e20c4077b47149565887551e425870b78fc9a
Author: Steve <steve@designerwallcoverings.com>
Date: Tue May 19 08:03:55 2026 -0700
JSON-serialise booking-page analytics values so a stray quote or newline cannot break the script
---
views/public/booking.ejs | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/views/public/booking.ejs b/views/public/booking.ejs
index 24fda84..7d98925 100644
--- a/views/public/booking.ejs
+++ b/views/public/booking.ejs
@@ -35,12 +35,24 @@
<%- include('../partials/footer') %>
<% if (booking.status === 'confirmed') { %>
+<%
+ // Script-context values must be JSON-serialised, not HTML-escaped: inside a
+ // script block HTML entities are not decoded, so the old escaped-output tag
+ // left raw apostrophes mangled and a newline / trailing backslash in
+ // business_name produced a JS SyntaxError that broke the whole inline
+ // script. JSON.stringify yields a valid JS string literal; the angle-bracket
+ // escape neutralises a literal closing script tag.
+ function jsLit(v) {
+ return JSON.stringify(String(v == null ? '' : v))
+ .replace(/</g, '\\u003c').replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029');
+ }
+%>
<script>
// GA4 conversion: booking_confirmed
gtag('event', 'booking_confirmed', {
- booking_uuid: '<%= booking.uuid %>',
- installer_slug: '<%= booking.installer_slug %>',
- installer_name: '<%= booking.business_name.replace(/'/g, "\\'") %>'
+ booking_uuid: <%- jsLit(booking.uuid) %>,
+ installer_slug: <%- jsLit(booking.installer_slug) %>,
+ installer_name: <%- jsLit(booking.business_name) %>
});
</script>
<% } %>
← 258f66a Constrain profile hero_url to the installer's own uploads, n
·
back to NationalPaperHangers
·
feat: add WebXR AR + gyro-clinometer wall measurement to /bo d08c846 →