'Scripts not working in React, NextJS project unless I specifically refresh the page
I had to refactor a large codebase built on pure HTML, CSS, and javascript into a ReactJS and NextJS application. The codebase had a whole lot of links and scripts whereby some scripts applied for all pages while some applied for only specific pages.
In the set-up I did, I created a Meta.js file where I kept all links and scripts and also created a Layout.js file which held the Meta.js as well a common navbar and sidebar layout which was applied to all pages.
The issue I am facing presently now is that some scripts/functionality do not work unless the page is refreshed. For instance, I enter the application from the homepage which is the index.js file, and then navigate to the settings page, which is a settings.js file.
The settings.js page has some tab that uses some script in it but will not work unless I reload the page. What can be the issue with this and how can I fix this.
Here are some of the important files listed below:
Meta.js
import React from 'react'
import Head from 'next/head'
import Script from 'next/script'
const Meta = ({title, keywords, description}) => {
return (
<>
<Head>
<meta charSet="utf-8" />
<meta content="Webflow" name="generator" />
</Head>
<Script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></Script>
<Script src='/CustomScript.js'></Script>
<Script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js' strategy='beforeInteractive' crossOrigin="anonymous"></Script>
<Script src='/webflow.js'></Script>
<Script src='https://fengyuanchen.github.io/datepicker/js/datepicker.js'></Script>
<Script src='https://cdn.jsdelivr.net/npm/flatpickr'></Script>
<Script src='https://cdn.quilljs.com/1.3.6/quill.js' strategy='beforeInteractive'></Script>
</>
)
}
export default Meta
Layout.js
import Nav from "./Nav";
import Meta from "./Meta";
const Layout = ({children}) => {
return (
<>
<Meta />
<Nav/>
<div className="body">
<main>
{children}
</main>
</div>
</>
);
}
export default Layout;
_app.js
// styles
import '../styles/normalize.css'
import '../styles/webflow.css'
import '../styles/listwise.webflow.css'
import '../styles/styles.css'
// website constant layout
import Layout from '../components/Layout'
function MyApp({ Component, pageProps }) {
return (
<Layout>
<Component {...pageProps} />
</Layout>
)
}
export default MyApp
Nav.js
import React from 'react'
import Image from 'next/image'
import Link from 'next/link'
const Nav = () => {
return (
<div className="app-nav-layout">
<Link href="#"><Image src="/listwise-logo-black-nospace.svg" width={130} height={130} alt="" className="left-navbar-logo" /></Link>
</div>
<nav role="navigation" className="left-navbar-menu w-nav-menu">
<Link href="/dashboard/listings/addListing">Create new listing</Link>
<Link href="/">Dashboard<br/></Link>
<Link href="/dashboard/listings/allListings"><a className="left-navbar-link w-nav-link"><span className="material-icons-round md-18 mr-8">list_alt</span> Listings<br/></a></Link>
<Link href="/dashboard/settings/settings">Account settings</Link>
<Link href="/dashboard/listings/myListwise">My Listwise</Link>
</nav>
</div>
)
}
export default Nav
settings.js
import React, {useState} from 'react'
import Head from "next/head"
import Script from "next/script"
const settings = () => {
return (
<>
<Head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css" />
<link rel="stylesheet" href="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css" />
<link rel="stylesheet" href="https://unpkg.com/filepond/dist/filepond.min.css" />
<Script src="https://unpkg.com/filepond-plugin-file-encode/dist/filepond-plugin-file-encode.min.js"></Script>
<Script src="https://unpkg.com/filepond/dist/filepond.min.js"></Script>
</Head>
<div className="app-main-layout-container">
<div className="tabs-menu w-tab-menu">
<a data-w-tab="Personal" className="tab-link w-inline-block w-tab-link w--current">
<div className="material-icons-round md-24 icon-acc-settings">person</div>
<div className="tab-text">Personal profile</div>
</a>
<a data-w-tab="Business" className="tab-link w-inline-block w-tab-link">
<div className="material-icons-round md-24 icon-acc-settings">store</div>
<div className="tab-text">Business profile</div>
</a>
<a data-w-tab="Social" className="tab-link w-inline-block w-tab-link">
<div className="material-icons-round md-24 icon-acc-settings">share</div>
<div className="tab-text">Social links</div>
</a>
</div>
<div className="tabs-content w-tab-content">
<div data-w-tab="Personal" className="w-tab-pane w--tab-active">
<div className="w-form">
<form id="wf-form-profile" name="wf-form-profile" data-name="profile" method="get">
<div className="form-group"><label htmlFor="name-4" className="label">Upload profile photo</label>
</form>
</div>
<div data-w-tab="Business" className="w-tab-pane">
<div className="w-form">
<form id="wf-form-profile" name="wf-form-profile" data-name="profile" method="get">
<div className="form-group"><label htmlFor="name-4" className="label">Business name</label>
<div className="hint marginb--20px">This is usually the name you work under</div><input type="text" className="input w-input" maxLength="256" name="Business-Name" data-name="Business Name" placeholder="Enter business name" id="business-name" required="" />
</form>
</div>
<div data-w-tab="Social" className="w-tab-pane">
<div className="w-form">
<form id="wf-form-profile" name="wf-form-profile" data-name="profile" method="get">
<div className="form-group"><label htmlFor="instagram-link" className="label">Instagram profile link</label><input type="text" className="input w-input" maxLength="256" name="Instagram-Link" data-name="Instagram Link" placeholder="www.instagram.com/myname" id="instagram-link" /></div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</>
)
}
export default settings
Also, I will like to ask how best to render those scripts that only work for specific pages, should I add the to the Meta.js file which gets loaded on the initial rendering of the application, or creates a separate file and add it to the page that needs it when the page is navigated to.
Solution 1:[1]
The Nextjs Script component can take a strategy prop. It has a default value of afterInteractive which means the script will first load the main javascript that's necessary for the page to become interactive before the script you've linked in the Script tag.
If you need any script to load early because some functionality of your page relies on it you'd want to set the strategy prop to beforeInteractive like so:
<Script src=" ... " strategy="beforeInteractive" />
More information on Next docs
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | dandan |
