Next.js Index.html and jQuery, Webshim, CSS Modules, and CSS Imports

Dean Gladish
8 min readJan 27, 2023

--

Next.js has a file-system based router built on the concept of pages.¹ Normally, URLs consist of many parts: the protocol, subdomain, domain, top-level domain (TLD), subfolder, slug, and parameters. There are two ways to make a slug readable:²

  • Use the “-” symbol. The advantage of using a hyphen is that when visitors enter a link, they don’t need to press caps lock.³
  • Use the Camel case method.⁴

In the App.js component we use React-router this way so far:⁵

<Router history={browserHistory}>
<Route path="/" component={Main}>
<IndexRoute component={Home}></IndexRoute>
<Route path="/profile/:slug" component={Split}></Route>
</Route>
</Router>

Then in the profile component we’re using Link to go to that specific profile via the slug:⁷

<Link to={'/profile/' + username.slug}>{username

Or we could use index.html, buried inside of the React components inside the application directory — public/index.html. Aside from Next.js we’re used to React.js index.html, a page template provided by the software by default which is written in basic hypertext markup language. It is the main HTML file of the React app that includes the React code and provides React with a platform on which to render. The index.html file contains a line of code → <div id=”root”></div> and it includes a div that acts as an entry point of the React application.⁶

In React.js index.html, the scope of jQuery’s access within script tags is that it manipulates the DOM directly and does not use the virtual DOM. Because jQuery is used when we create an app, then at that time we need a library of functions that do not have React.js or do not have their own React component. This makes it easy to manipulate HTML documents, do traversing, event handling, etc.⁸

All from within the /pages folder,

Next.js does a lot of magic to handle server-side rendering, static-site generation, and code splitting. Next.js is universal in server-side loading first and client-side loading second when accessing the client-side window object.⁹

It’s important to know that components within the /pages folder work a little differently from a regular React component:

  • There’s a top-level syntax rule for using the import keyword, and we can import within componentDidUpdate or jQuery.¹⁰
  • Put our page components inside the /page folder. Components inside this folder can have a default export (the component), along with named exports (the additional Next.js-specific functions like getStaticProps). If Next.js finds the exported functions, it will run them.¹¹
  • Use next/dynamic only for dynamic imports. Dynamic imports are lazy-loaded — this will affect Next.js’ automatic code-splitting and potentially server-side rendering. With regard to the exact inner workings, dynamically loading a Page component, which is special in Next, could break things.¹²
  • Only use dynamic imports with a 3rd-party component that breaks SSR and needs dynamic import so it’s not server-side rendered.¹³

When naming CSS and CSS modules imports, the recommended convention is to use camelCase to name our CSS/SCSS classNames. But if we still want to use kebab-case for our className, then use it with the bracket notation.¹⁴

component.module.scss

.login-button { 
/* some scss styling */
}¹⁵

component.jsx

<button className={styles['login-button']}>Login</button>¹⁶

Next.js supports CSS Modules using the [name].module.css file naming convention. CSS Modules locally scope CSS by automatically creating a unique class name. This allows us to use the same CSS class name in different files without worrying about collisions. In production, all CSS files will be automatically concatenated into a single minified .css file.¹⁷

Global stylesheet CSS imports

Consider the following stylesheet name styles.css:

body {
font - family: 'SF Pro Text', 'SF Pro Icons', 'Helvetica Neue', 'Helvetica', 'Arial', sans - serif;
padding: 20 px 20 px 60 px;
max - width: 680 px;
margin: 0 auto;
}¹⁸

Create a pages/_app.js file if not already present. Then, import the styles.css file. This default export is required in a new pages/_app.js file.¹⁹

import '../styles.css'
export default function MyApp({ Component, pageProps }) { 
return <Component {...pageProps} />
}²⁰

For global stylesheets, like bootstrap or nprogress, we should import the file inside pages/_app.js. For example:

import 'bootstrap/dist/css/bootstrap.css'
export default function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}¹⁷

For importing CSS required by a third party component,

we can do so in our component. For example,

components/ExampleDialog.js:

import { useState } from 'react'
import { Dialog } from '@reach/dialog'
import VisuallyHidden from '@reach/visually-hidden'
import '@reach/dialog/styles.css'
function ExampleDialog(props) {
const [showDialog, setShowDialog] = useState(false)
const open = () => setShowDialog(true)
const close = () => setShowDialog(false)
return (
<div>
<button onClick={open}>Open Dialog</button>
<Dialog isOpen={showDialog} onDismiss={close}>
<button className="close-button" onClick={close}>
<VisuallyHidden>Close</VisuallyHidden>
<span aria-hidden>×</span>
</button>
<p>Hello there. I am a dialog</p>
</Dialog>
</div>
)
}²¹

Third-party apps

Now we can use third-party apps like react-datepicker

import ‘./react-datepicker-cssmodules.css’;

where our file location is, and otherwise we can add css file in public/index.html file in our react app like the old alternative, the html way²²

<link rel=”stylesheet” href=”path_of_our_css_file”>
<link rel=”stylesheet” href=”react-datepicker-cssmodules.css”>

The Webshim Library with Dependencies

Script tags are so useful, to use the Webshim lib we need to include the dependencies jQuery and Modernizr alongside the Webshim Lib.

<script src="scripts/jquery-1.8.2.min.js"></script>
<script src="scripts/modernizr-custom.js"></script>
<script src="scripts/webshim/polyfiller.js"></script>

Now let’s initialize Webshim and, if needed, tell it which features we want to use.²³

<script>
// Polyfill all unsupported features
$.webshim.polyfill();
</script>
<script>
// Polyfill only form and canvas features
$.webshim.polyfill('forms canvas');
</script>

And that’s it! Webshim will automatically detect and polyfill missing features depending on the user’s browser. If you are curious the full feature list is:

  • json-storage
  • es5
  • geolocation
  • canvas
  • forms
  • forms-ext
  • mediaelement
  • track
  • details²³

Start out with the <video> tag on the basic page without Webshim or any other polyfill:

<!DOCTYPE html>
<html>
<head>
<title>Video native</title>
</head>
<body>
<video width="480" height="360" controls="controls">
<source src="Video.mp4" type="video/mp4">
<source src="Video.webm" type="video/webm">
</video>
</body>
</html>

Modern browsers will display this video correctly, but Internet Explorer 6, 7 or 8 will not. Now we change the example to embed the Webshim Lib. See that it’s not necessary to edit anything else. Webshim and polyfill will make this video accessible. The modern browser will display its native <video> tag player but now this functionality is also available in Internet Explorer 6+.²³

<!DOCTYPE html>
<html>
<head>
<title>Video including polyfill</title>
<script src="scripts/jquery-1.8.2.min.js"></script>
<script src="scripts/modernizr-custom.js"></script>
<script src="scripts/webshim/polyfiller.js"></script>
<script>
$.webshim.polyfill('mediaelement');
</script>
</head>
<body>
<video width="480" height="360" controls="controls">
<source src="Video.mp4" type="video/mp4">
<source src="Video.webm" type="video/webm">
</video>
</body>
</html>²³

Aside from pages/_app.js CSS imports, script tags, and importing CSS required by a third party component, in your component, bracket notation and kebab-case, bootstrap and nprogress used as global stylesheets within the single minified .css file in production, it’s important to understand how the production builds.²⁴

The Window Object as it is in Next.js

In Next.js, since the window object is the client-side global scope which exists after the server-side JavaScript environment is created, index.html and React App component libraries which want the window object should have access once the client-side renders. The window object addresses an open window in a program. On the off chance that a record contains outlines (<iframe> labels), the program makes one window object for the HTML report, and one extra window object for each casing.²⁵

At the point when we need a library that doesn’t have its own React part or probably won’t work correspondingly to React — for instance, jQuery, we need to give a ‘ref’, which provides an interface to get to DOM hubs that are characterized in the render method of a React part. We can make a ref using the React.createRef() method. To get the real DOM component, pass the ref to the findDOMNodes() method of react-dom as we will control the DOM hub directly.²⁶

Let’s use jQuery in React, and why?

At the top we can write: import $ from ‘jquery’;. Now inside we can write $('#main') to access main.

Sometimes when we are building large applications, we might want to use jQuery plugins or jQuery functionality to do things that aren’t possible in React. The advantage of using React is that each component can maintain its own state independent of other components.²⁷

Since many web apps are developed using jQuery, we might want our React component to integrate with the jQuery app. For example, we might want to show some data within our React application. Similarly, we may have an existing jQuery app and want our React app to send data to the jQuery app for rendering on the page.²⁸

Communicating between the React side of the app and jQuery is actually easy to implement. There are three different ways to do this:

  • Referencing jQuery context from React
  • Using helper class, which is passed to React
  • Using a publisher/subscriber object passed to React²⁸

Do jQuery in React with a guide!

There is no right way to use both jQuery and React together. jQuery manipulates the DOM by, for example, selecting elements and adding/deleting stuff into/from them. Typically, it selects an existing <div> and sets its text. The other frameworks don’t manipulate the DOM; they generate it from data, and regenerate it whenever this data changes (for instance after an Ajax call).

The problem is, jQuery has no clue about React’s presence and actions, and React has no clue about jQuery’s presence and actions. This will necessarily lead to a broken application, full of hacks and workarounds, unmaintainable, not to mention that we have to load two libraries instead of one.

For instance, jQuery will select a <button> and add it a .click() listener; but a split second later, React/Angular/Vue might regenerate the DOM and the button in the process, voiding jQuery’s .click().

The solution is, use jQuery OR (React/Angular/Vue), not both together.²⁹

[1] Routing: Introduction | Next.js
https://nextjs.org/docs/routing/introduction

[2] URL Slugs: How to Create SEO-Friendly URLs (10 Easy Steps)
https://seosherpa.com/url-slugs/

[3] What is a URL slug? | Short.Io Help Center
https://help.short.io/en/articles/4065948-what-is-a-url-slug

[4] What is the CamelCase naming convention?
https://www.techtarget.com/whatis/definition/CamelCase#:~:text=What%20is%20CamelCase%3F,humps%20on%20a%20camel's%20back.

[5] React Router 6 — Tutorial for Beginners — YouTube
https://www.youtube.com/watch?v=59IXY5IDrBA

[6] A quick guide to help you understand and create ReactJS apps
https://www.freecodecamp.org/news/quick-guide-to-understanding-and-creating-reactjs-apps-8457ee8f7123/

[7] javascript — ReactJS- Use slug instead of Id in the URL with React router — Stack Overflow
https://stackoverflow.com/questions/42659611/reactjs-use-slug-instead-of-id-in-the-url-with-react-router

[8] How to integrate a React application with jQuery
https://www.educative.io/answers/how-to-integrate-a-react-application-with-jquery

[9] Reddit — Dive into anything
https://www.reddit.com/r/reactjs/comments/zprham/why_do_people_like_using_nextjs/

[10] Solved In React syntax, instead of using the import keyword | Chegg.com
https://www.chegg.com/homework-help/questions-and-answers/react-syntax-instead-using-import-keyword-top-level-use-import-keyword-within-jquery-withi-q85761074

[11] Data Fetching: getStaticProps | Next.js
https://nextjs.org/docs/basic-features/data-fetching/get-static-props

[12] When should you not use the `next/dynamic`? · Discussion #32895 · vercel/next.js
https://github.com/vercel/next.js/discussions/32895

[13] Using Non-SSR Friendly Components with Next.js | by Piumi Liyana Gunawardhana | Bits and Pieces
https://blog.bitsrc.io/using-non-ssr-friendly-components-with-next-js-916f38e8992c

[14] CSS modules — converting class names to camelCase automatically · Discussion #11267 · vercel/next.js
https://github.com/vercel/next.js/discussions/11267

[15] CSS Buttons
https://www.w3schools.com/css/css3_buttons.asp

[16] Bootstrap Buttons
https://www.w3schools.com/bootstrap/bootstrap_buttons.asp

[17] Basic Features: Built-in CSS Support | Next.js
https://nextjs.org/docs/basic-features/built-in-css-support

[18] next.js/css-global.md at canary · vercel/next.js
https://github.com/vercel/next.js/blob/canary/errors/css-global.md

[19] javascript — Next.js — import css file does not work — Stack Overflow
https://stackoverflow.com/questions/50149729/next-js-import-css-file-does-not-work

[20] Advanced Features: Custom `App` | Next.js
https://nextjs.org/docs/advanced-features/custom-app

[21] Dialog (Modal) — Reach UI
https://reach.tech/dialog/

[22] javascript — react-datepicker styles are not being not applied on deployed build — Stack Overflow
https://stackoverflow.com/questions/58955113/react-datepicker-styles-are-not-being-not-applied-on-deployed-build

[23] How to Use the Webshims Polyfill | CSS-Tricks — CSS-Tricks
https://css-tricks.com/how-to-use-the-webshims-polyfill/

[24] RFC: Importing CSS from Third Party React Components · Discussion #15208 · vercel/next.js
https://github.com/vercel/next.js/discussions/15208

[25] Solved In Next.js, since the window object is the | Chegg.com
https://www.chegg.com/homework-help/questions-and-answers/nextjs-since-window-object-client-side-global-scope-exists-server-side-javascript-environm-q85761333

[26] Refs and the DOM — React
https://reactjs.org/docs/refs-and-the-dom.html

[27] How do I use jquery in react app? | by King Rayhan | Medium
https://kingrayhan.medium.com/how-do-i-use-jquery-in-react-app-976c124f5448

[28] How to Use jQuery Inside a React Component | Pluralsight
https://www.pluralsight.com/guides/how-to-use-jquery-inside-a-react-component

[29] javascript — What is the right way to use Jquery in React? — Stack Overflow
https://stackoverflow.com/questions/51304288/what-is-the-right-way-to-use-jquery-in-react

--

--