Skip to content

Commit

Permalink
fix: Minimize cloudflare warnings
Browse files Browse the repository at this point in the history
Fix #30 #32
  • Loading branch information
marsidev committed Aug 31, 2023
1 parent 56fe707 commit abc4bb7
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 17 deletions.
33 changes: 23 additions & 10 deletions packages/lib/src/lib.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
DEFAULT_CONTAINER_ID,
DEFAULT_ONLOAD_NAME,
DEFAULT_SCRIPT_ID,
checkElementExistence,
getTurnstileSizeOpts,
injectTurnstileScript
} from './utils'
Expand Down Expand Up @@ -41,13 +42,15 @@ export const Turnstile = forwardRef<TurnstileInstance | undefined, TurnstileProp
const firstRendered = useRef(false)
const [widgetId, setWidgetId] = useState<string | undefined | null>()
const [turnstileLoaded, setTurnstileLoaded] = useState(false)
const scriptId = scriptOptions?.id || DEFAULT_SCRIPT_ID
const scriptLoaded = useObserveScript(scriptId)
const containerId = id ?? DEFAULT_CONTAINER_ID
const scriptId = injectScript
? scriptOptions?.id || `${DEFAULT_SCRIPT_ID}__${containerId}`
: scriptOptions?.id || DEFAULT_SCRIPT_ID
const scriptLoaded = useObserveScript(scriptId)

const onLoadCallbackName = scriptOptions?.onLoadCallbackName
? `${scriptOptions.onLoadCallbackName}#${containerId}`
: DEFAULT_ONLOAD_NAME
? `${scriptOptions.onLoadCallbackName}__${containerId}`
: `${DEFAULT_ONLOAD_NAME}__${containerId}`

const renderConfig = useMemo(
(): RenderOptions => ({
Expand Down Expand Up @@ -179,9 +182,15 @@ export const Turnstile = forwardRef<TurnstileInstance | undefined, TurnstileProp

useEffect(() => {
if (injectScript && !turnstileLoaded) {
injectTurnstileScript({ onLoadCallbackName, scriptOptions })
injectTurnstileScript({
onLoadCallbackName,
scriptOptions: {
...scriptOptions,
id: scriptId
}
})
}
}, [injectScript, turnstileLoaded, onLoadCallbackName, scriptOptions])
}, [injectScript, turnstileLoaded, onLoadCallbackName, scriptOptions, scriptId])

/* if the script is injected by the user, we need to wait for turnstile to be loaded
and set turnstileLoaded to true. Different from the case when handle the injection,
Expand Down Expand Up @@ -210,7 +219,9 @@ export const Turnstile = forwardRef<TurnstileInstance | undefined, TurnstileProp
// re-render widget when renderConfig changes
useEffect(() => {
if (containerRef.current && widgetId) {
window.turnstile!.remove(widgetId)
if (checkElementExistence(widgetId)) {
window.turnstile!.remove(widgetId)
}
const newWidgetId = window.turnstile!.render(containerRef.current, renderConfig)
setWidgetId(newWidgetId)
firstRendered.current = true
Expand All @@ -219,10 +230,12 @@ export const Turnstile = forwardRef<TurnstileInstance | undefined, TurnstileProp
}, [renderConfigStringified, siteKey])

useEffect(() => {
if (!window.turnstile) return
if (!widgetId) return
if (!checkElementExistence(widgetId)) return

return () => {
if (widgetId && window.turnstile) {
window.turnstile!.remove(widgetId)
}
window.turnstile!.remove(widgetId)
}
}, [widgetId])

Expand Down
4 changes: 2 additions & 2 deletions packages/lib/src/use-observe-script.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useEffect, useState } from 'react'
import { DEFAULT_SCRIPT_ID, isScriptInjected } from './utils'
import { DEFAULT_SCRIPT_ID, checkElementExistence } from './utils'

export default function useObserveScript(scriptId = DEFAULT_SCRIPT_ID) {
const [scriptLoaded, setScriptLoaded] = useState(false)

useEffect(() => {
const checkScriptExists = () => {
if (isScriptInjected(scriptId)) {
if (checkElementExistence(scriptId)) {
setScriptLoaded(true)
}
}
Expand Down
16 changes: 11 additions & 5 deletions packages/lib/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import { ContainerSizeSet, InjectTurnstileScriptParams, RenderOptions } from './
export const SCRIPT_URL = 'https://challenges.cloudflare.com/turnstile/v0/api.js'
export const DEFAULT_SCRIPT_ID = 'cf-turnstile-script'
export const DEFAULT_CONTAINER_ID = 'cf-turnstile'
export const DEFAULT_ONLOAD_NAME = `onloadTurnstileCallback#${DEFAULT_CONTAINER_ID}`
export const DEFAULT_ONLOAD_NAME = 'onloadTurnstileCallback'

/**
* Function to check if script has already been injected
* Function to check if an element with the given id exists in the document.
*
* @param scriptId
* @param id Id of the element to check.
* @returns
*/
export const isScriptInjected = (scriptId: string) => !!document.querySelector(`#${scriptId}`)
export const checkElementExistence = (id: string) => !!document.getElementById(id)

/**
* Function to inject the cloudflare turnstile script
Expand All @@ -26,7 +26,7 @@ export const injectTurnstileScript = ({
}: InjectTurnstileScriptParams) => {
const scriptId = id || DEFAULT_SCRIPT_ID

if (isScriptInjected(scriptId)) {
if (checkElementExistence(scriptId)) {
return
}

Expand All @@ -35,6 +35,12 @@ export const injectTurnstileScript = ({

script.src = `${SCRIPT_URL}?onload=${onLoadCallbackName}&render=${render}`

// Prevent duplicate script injection with the same src
if (document.querySelector(`script[src="${script.src}"]`)) {
console.log('Script already loaded', { scriptSrc: script.src })
return
}

script.defer = !!defer
script.async = !!async

Expand Down

0 comments on commit abc4bb7

Please sign in to comment.