Script delay to load
Unanswered
Gabriel Moresco posted this in #help-forum
Hello guys, I have a script inside my NextJS 14 app, that render a form from my CRM (Bitrix24).
### bitrix-establishment-form.js
The only way I found to work is this:
### EstablishmentForm.tsx
I put the
I tried to use Next
But another problem arises, the form is rendered in the end of the
I tried to use the
Could you help me to make this work, the form render when the page load?
### bitrix-establishment-form.js
;(function (w, d, u) {
const s = d.createElement('script')
s.async = true
s.src = u + '?' + ((Date.now() / 180000) | 0)
const h = d.getElementsByTagName('script')[0]
h.parentNode.insertBefore(s, h)
})(window, document, 'https://cdn.bitrix24.com.br/{{SCRIPT_ID}}/crm/form/loader_14.js')The only way I found to work is this:
### EstablishmentForm.tsx
'use client'
import { useEffect } from 'react'
export const EstablishmentForm = () => {
useEffect(() => {
const scriptId = '/scripts/bitrix-establishment-form.js'
if (document.getElementById(scriptId) != null) {
return
}
const script = document.createElement('script')
script.id = scriptId
script.src = scriptId
script.setAttributeNS(null, 'data-b24-form', 'inline/{{ID}}/{{ID}}')
script.setAttributeNS(null, 'data-skip-moving', 'true')
script.defer = true
const scriptDiv = document.getElementById('script_div')
scriptDiv?.appendChild(script)
return () => {
scriptDiv?.removeChild(script)
}
}, [])
return <div id='script_div' className='w-full' />
}I put the
EstablishmentForm component inside a div. But there is a problem, the form only renders a few seconds after the page finishes loading.I tried to use Next
Script:<Script
src='/scripts/bitrix-establishment-form.js'
data-b24-form='inline/14/vle4l0'
data-skip-moving='true'
/>But another problem arises, the form is rendered in the end of the
body, after everything in the page, but I read that this is the expected behavior (I think).I tried to use the
strategy='beforeInteractive'. The <script> is loaded in the <head> of the app, but the form is not rendered on the screen.Could you help me to make this work, the form render when the page load?
20 Replies
Cape lion
I have the same problem
Up
up
up
Toyger
you need to check does your form have some distinguishable id
then add some id to div where you want to place it
bitrix24 have custom form event on init you can use it in use effect
then add some id to div where you want to place it
bitrix24 have custom form event on init you can use it in use effect
useEffect(() => {
const handleFormInit = () => {
const targetDiv = document.getElementById("your_target_div_id");
const formDiv = document.getElementById("your_FORM_div_id");
if (formDiv && targetDiv) {
targetDiv.appendChild(formDiv);
}
};
window.addEventListener('b24:form:init', handleFormInit);
return () => {
window.removeEventListener('b24:form:init', handleFormInit);
};
}, []);@Toyger you need to check does your form have some distinguishable id
then add some id to div where you want to place it
bitrix24 have custom form event on init you can use it in use effect
js
useEffect(() => {
const handleFormInit = () => {
const targetDiv = document.getElementById("your_target_div_id");
const formDiv = document.getElementById("your_FORM_div_id");
if (formDiv && targetDiv) {
targetDiv.appendChild(formDiv);
}
};
window.addEventListener('b24:form:init', handleFormInit);
return () => {
window.removeEventListener('b24:form:init', handleFormInit);
};
}, []);
but it will still continue loading form after rendering the screen, right?
Maybe I didn't understand the way you suggested
'use client'
export const EstablishmentForm = () => {
return (
<>
<script
src='/scripts/bitrix-establishment-form.js'
data-b24-form='inline/14/vle4l0'
data-skip-moving='true'
defer
onLoad={() => {
const formContainer = document.getElementById('establishment-form-container')
const form = document.getElementsByClassName('b24-form')[0]
if (formContainer && form) {
formContainer.appendChild(form)
}
}}
/>
<div id='establishment-form-container' className='flex flex-1' />
</>
)
}it worked, but the form is rendered after the page load
@Gabriel Moresco it worked, but the form is rendered after the page load
Toyger
it's external script, so it basically impossible to load it with your page.
theoretically you can add it directly to layout for your page, but even if it will work, it will be only for direct page open, if you redirect with user with client side rendering it will probably ignore layout file.
theoretically you can add it directly to layout for your page, but even if it will work, it will be only for direct page open, if you redirect with user with client side rendering it will probably ignore layout file.
@Toyger it's external script, so it basically impossible to load it with your page.
theoretically you can add it directly to layout for your page, but even if it will work, it will be only for direct page open, if you redirect with user with client side rendering it will probably ignore layout file.
Even if I use the Next Script
I tried this, but the script is loaded in the
strategy='beforeInteractive'?I tried this, but the script is loaded in the
head and not rendered on the page@Gabriel Moresco Even if I use the Next Script `strategy='beforeInteractive'`?
I tried this, but the script is loaded in the `head` and not rendered on the page
is it possible to share the script so I can try?
@Ray is it possible to share the script so I can try?
Yes, i created a repo for it
@Gabriel Moresco i created 3 components, that is the three ways i tried to work
try this
"use client";
import { ComponentRef, useEffect, useRef } from "react";
export default function Page() {
const formref = useRef<ComponentRef<"div">>(null);
useEffect(() => {
if (formref.current) {
const script = document.createElement("script");
script.id = "b24form";
script.innerHTML = `(function (w, d, u) {
const s = d.createElement("script");
s.async = true;
s.src = u + "?" + ((Date.now() / 180000) | 0);
const h = d.getElementsByTagName("script")[0];
h.parentNode.insertBefore(s, h);
})(
window,
document,
"https://cdn.bitrix24.com.br/b25948707/crm/form/loader_14.js"
);`;
script.setAttributeNS(null, "data-b24-form", "inline/14/vle4l0");
script.setAttributeNS(null, "data-skip-moving", "true");
script.defer = true;
formref.current.appendChild(script);
return () => {
document.getElementById("b24form")?.remove();
};
}
}, []);
return (
<div className="grid grid-cols-2">
<div className="flex justify-center items-center">1</div>
<div ref={formref} className="min-h-[500px]"></div>
</div>
);
}@Gabriel Moresco I tried, but the form still render after the page load
it has to be loaded after the page load because the form is loaded from a javascript script
otherwise, you would have to make the form yourself and make a POST request to their endpoint when the form is submitted