An issue with qr-code-styling in Nextjs: 'self' is not recognized


"import user";
import { Button } from "@/components/ui/button";
import QRCodeStyling from "qr-code-styling";
import { useEffect, useState } from "react";

const ShareButton = ({ recipe }: any) => {
    const [qrPopupIsOpen, setQrPopupIsOpen]: any = useState(false);
    const [qrCode, setQRCodeInstance] = useState<QRCodeStyling | null>(
        null
    );

    useEffect(() => {
        if (qrPopupIsOpen) {
            const qrCode = new QRCodeStyling({
                width: 300,
                height: 300,
                backgroundOptions: {
                    color: "transparent",
                },
                dotsOptions: {
                    type: "classy-rounded",
                },
                data: `/recipes/${recipe.id}`,
                imageOptions: {
                    crossOrigin: "anonymous",
                    margin: 20,
                },
            });

            setQRCodeInstance(qrCode);
        }
    }, [qrPopupIsOpen]);

    const toggleQrPopup = () => {
        setQrPopupIsOpen(!qrPopupIsOpen);
    };

    const openSharePopup = () => {
        toggleQrPopup();
    };

    return (
        <div>
            <Button variant="outline" className="w-full" onClick={openSharePopup}>
                Share
            </Button>
            {qrPopupIsOpen && qrCode && (
                <div className="fixed top-0 left-0 w-full h-screen flex items-center justify-center bg-neutral-950/25 backdrop-blur-sm z-[999]">
                    <div className="bg-neutral-200 p-8 rounded-xl relative max-w-[90vw] max-h-[90vh] overflow-auto">
                        <button
                            className="absolute top-4 right-4 text-gray-600 hover:text-gray-800"
                            onClick={toggleQrPopup}
                        >
                            <p>close</p>
                        </button>

                        <div
                            className="bg-transparent"
                            ref={(node) => node && qrCode?.append(node)}
                        />
                    </div>
                </div>
            )}
        </div>
    );
};

export default ShareButton;

I encountered an issue with a status 500 error code and the message "self is not defined" in the console. Although my code executes correctly on the UI, this error persists.

The primary goal is to display a QR code within a popup without encountering any console errors.


GET /recipes 500 in 397ms
 ⨯ ReferenceError: self is not defined
    at __webpack_require__ (/Users/yevheniiasimaka/Desktop/recipe-website/.next/server/webpack-runtime.js:33:43)

Despite efforts to resolve the issue by wrapping the code in useEffect as recommended, the "self is not defined" error remains persistent. This problem arose while developing a recipe website with a QR code sharing feature.

https://i.sstatic.net/Tp9f2c6J.png

Answer №1

This issue has been identified and documented in issue #89 as well as issue 172. The current limitation of the qr-code-styling library is that it can only function on the client side due to its dependency on the window object, which is not accessible on the server side.

Solution 1: Implement Dynamic Import using next/dynamic for ShareBtn component

const ShareBtn = dynamic(() => import('@/path/to/ShareBtn'), {
  ssr: false,
});

Solution 2: ES6 Dynamic Import Approach

Another approach is to utilize the ES6 import() method to dynamically load the qr-code-styling library within the ShareBtn component when required:


const ShareBtn = ({ recipe }: any) => {
    // other code
    const [qrCode,setQrCode] = useState();
    const ref = useRef(null);

    useEffect(() => {
        if (ref.current && qrCode) {
            qrCode.append(ref.current);
        }
    }, [ref, qrCode]);


    useEffect(() => {
        // Dynamically import qr-code-styling only client-side
        if (ref.current) {
            import("qr-code-styling").then(({default: QRCodeStyling}) => {
                const qrCode = new QRCodeStyling({
                   width: 300,
                   height: 300,
                   backgroundOptions: {
                       color: "transparent",
                   },
                   dotsOptions: {
                       type: "classy-rounded",
                   },
                   data: `/recipes/${recipe.id}`,
                   imageOptions: {
                       crossOrigin: "anonymous",
                       margin: 20,
                   },
                });

                setQrCode(qrCode);
            });
        }
    }, [ref]);

   return (
        <div ref={ref}/>
    );
}

Both solutions ensure that the qr-code-styling library is only loaded in the browser environment, preventing errors related to self not defined on the server.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Following the creation of the image, the functionality of the Next.js app seems to be compromised

I encountered an issue after creating a Docker image. When I build applications without Docker using npm commands, everything seems to be working fine. Screenshots are provided below. Can anyone suggest a solution to this problem? Here is the Dockerfile ...

Encountered an issue with running tests in vscode-test - runTests function throwing

Setting up tests for my vscode extension for the first time and encountering an issue. I copied and pasted the example from code.visualstudio's /working-with-extensions/testing-extension. However, I'm facing an error when trying to call runTest ...

Tips for choosing the node_modules distribution flavor to include in your webpack bundle

Issue: Following the update of AJV.js to Version 6.4, my vendor bundle now includes the "uri-js" ESNEXT version instead of the ES5 version, causing compatibility issues with IE11. Analysis: Upon investigation, I discovered that AJV references uri-js usi ...

Why is it advantageous to use Observable as the type for Angular 5 component variables?

Being a beginner in Angular 6, I have been exploring the process of http mentioned in this link: https://angular.io/tutorial/toh-pt6#create-herosearchcomponent One thing that caught my attention was that the heroes array type is set to Observable in the ...

Learn the technique of passing dual onClick parameters to a single function in React

I am working on a function named Test where I need to pass two onClick references. const Test = ({ onConnect }:{ onConnect:any }, { onDisconnect }:{ onDisconnect:any }) => { return ( <div> <DrawDiagram /> <button onClick ...

What is the function of the OmitThisParameter in TypeScript when referencing ES5 definitions?

I came across this specific type in the ES5 definitions for TypeScript and was intrigued by its purpose as the description provided seemed quite vague. /** * Removes the 'this' parameter from a function type. */ type OmitThisParameter<T> ...

Modify the code to use a BehaviorSubject subscribing to an Observable

Currently, I am in the process of learning Angular2 and RxJS by studying someone else's application. The application consists of two modules: asObservable.ts export function asObservable(subject: Subject) { return new Observable(fn => subject ...

Navigating json data in angular 6

I retrieved a JSON object in the following format response = [ { 'a': [ { 'b': [ { 'c': [ { 'name': 'abc', 'value': 900 ...

The issue with Elastic UI in NextJS is that it does not recognize the Window as defined

Struggling to integrate a button component from the Elastic UI library into my code. Every time I try to add the button, I encounter a window is not defined error. The API call and other functionalities work smoothly until I introduce the button component ...

Use a react-hook to dynamically set a custom favicon for Safari

I have a basic React hook application built with Next.js where I am trying to dynamically update the favicon. In my index.js file, I have: import React from "react"; import Head from "next/head"; import { useTheme } from "@emotion/ ...

How can I stop the SvelteKit production node server from filling up the logs with "Error: not found /path/here"?

After developing a website using sveltekit, I decided to build it for production as a nodejs server and deploy it on my linux server with Caddy as a reverse proxy. Unexpectedly, upon starting the server, I began receiving error messages in the log such as ...

Angular - Evaluating the differences between the object model and the original model value within the view

To enable a button only when the values of the 'invoice' model differ from those of the initial model, 'initModel', I am trying to detect changes in the properties of the 'invoice' model. This comparison needs to happen in th ...

Export interface for material-ui wrapper to cast any type in TypeScript (React)

I work with React using TypeScript. Recently, I encountered an issue with exporting. I'm creating an interface that encapsulates components from Material-ui. Here is a simplified example: Wrapping.tsx import { default as Component, ComponentProps ...

I have been utilizing ESBuild to compile JavaScript code for browser usage. However, I encountered an issue when trying to import CSS as I received an error message stating "Unexpected '.'". Can anyone provide guidance on how to resolve this issue?

I am currently developing a JavaScript notebook that operates within the browser environment. To compile my code, I have chosen to utilize ESBuild. My primary objective is to enable the handling of CSS imports such as <import 'bulma/css/bulma.css&a ...

Is it correct to implement an interface with a constructor in TypeScript using this method?

I am completely new to TypeScript (and JavaScript for the most part). I recently came across the article discussing the differences between the static and instance sides of classes in the TypeScript handbook. It suggested separating the constructor into an ...

Managing individual HTTP responses within Angular 6

I currently have 15 HTTP requests being sent to the API individually. Instead of waiting for all requests to finish processing (especially one that can take a few minutes), I want to handle responses as they come in. On the service side: findOneByOne ...

Relationship requirement between two attributes of an entity

My goal is to enhance the types for a frontend route configuration object by linking the `path` and `prepare` fields together. This way, the `prepare` function field will receive the appropriate parameters based on the `:keys` in the path. Each route item ...

What is the best way to send information from a component on one page to a component on another page in React/Next.js?

Overview In my Next.js application, I have two pages: index.js and results.js. The index page features two Location Autocomplete fields that provide the address and LatLng of a selected location. This data is stored in a variable named markers on the inde ...

Enhancing Text Editing in NEXT.js

I am currently working on an administration panel where users can edit promotions on the site using a project built on NEXT.js (React). As a beginner, I am looking to create an independent text editor tool that allows users to format text with paragraphs, ...

Executing JavaScript file using TypeScript code in Node.js

Is it possible to execute a JS file from TypeScript code in Node.js? One way to achieve this is by exposing the global scope and assigning values to it. For example: Global Scope (TypeScript): globalThis.names = ['Joe', 'Bob', 'J ...