Handling Script Tags on Next.js Route Changes
- #Tips & Tricks
- #Features
When building websites with Next.js and Sanity, you might encounter a common challenge: managing custom HTML that includes <script>
tags. By default, these scripts only execute on the initial page load, but what if you need them to run again after route changes? Let's explore how this is effectively handled in SanityPress with the help of the Custom HTML module.
The Challengeπ
In Next.js applications, client-side navigation doesn't trigger a full page reload. While this provides a smooth user experience, it can cause issues with custom scripts that need to re-execute after route changes. This is particularly important when working with embedded content or third-party widgets.
The Solutionπ
We've implemented a custom component in SanityPressβthe Custom HTML moduleβ that handles this scenario elegantly. Here's how it works:
- We use a combination of
useRef
anduseState
to track the component's render state. - The component maintains a
firstRender
flag to handle initial mounting. - On subsequent renders, we:
- Create a new DOM fragment from the HTML string
- Append it to our container element
Here's the implementation:
'use client'
import { useEffect, useRef, useState } from 'react'
export default function CustomHTML({ code }: { code?: string }) {
const ref = useRef<HTMLElement>(null)
const [firstRender, setFirstRender] = useState(true)
if (!code) return null
// if no <script> tag, render as is
if (!code.includes('<script'))
return (
<section dangerouslySetInnerHTML={{ __html: code }} />
)
// if includes <script> tag, ensure script is re-run on each render
useEffect(() => {
if (firstRender) {
setFirstRender(false)
} else {
const parsed = document
.createRange()
.createContextualFragment(code)
ref.current?.appendChild(parsed)
}
}, [ref.current, code])
return (
<section ref={ref} />
)
}
Best Practicesπ
While this solution works well, consider these best practices:
- Only use custom scripts when absolutely necessary.
- Prefer Next.js's built-in
next/script
component when possible. - Be cautious with third-party scripts and their impact on performance and security.
- Always sanitize HTML content before rendering.
Example Use Case in SanityPressπ
Imagine you have a content block in your CMS where users can embed custom HTML. You donβt want scripts within this block to execute multiple times on each page transition. By implementing the Custom HTML module, you ensure that scripts run cleanly and predictably, improving performance and avoiding errors.
Conclusionπ
Managing script execution in Next.js doesn't have to be complicated. With this solution implemented in SanityPress, you can confidently handle custom HTML content that includes scripts, ensuring they work correctly throughout your application's lifecycle.