What are the steps to integrate openjphjs with next.js?

I am working on a project with Next.js and need to utilize openjphjs for decoding HTJ2K pixel data.

In order to incorporate openjphjs, I have included both openjphjs.js and openjphjs.wasm in a specific folder within the project structure.

To address an error that arose, I made the following adjustments to the next.config.js file:

    webpack: (config) => {
        config.resolve.fallback = { fs: false };
        return config;
    },

These modifications were aimed at resolving the issue highlighted by the error message:

Module not found: Can't resolve 'fs'

Following guidance from the example provided, I attempted the following implementation:

import openjphjs from './openjphjs/openjphjs.js';

const decode = () => {
   const decoder = new openjphjs.HTJ2KDecoder();
}

Unfortunately, this approach resulted in multiple errors being thrown:

GET http://localhost:3000/_next/static/chunks/openjphjs.wasm 404 (Not Found)
Uncaught (in promise) RuntimeError: Aborted(RuntimeError: Aborted(both async and sync fetching of the wasm failed).
Uncaught TypeError: _openjphjs_openjphjs_js__WEBPACK_IMPORTED_MODULE_8___default(...).HTJ2KDecoder is not a constructor

Experimentally, I also tried relocating openjphjs.wasm to the indicated path, as well as placing the files in the /public directory, but the issues persisted.

Answer №1

Experimented with integrating OpenJPH into a Next.js 14.1.1 app router project, and successfully instantiated it on the client side using the following steps:

  1. The first step is to place both openjphjs.js and openjphjs.wasm in your project's /public directory.

  2. Next, create a server-side page route (e.g., app/openjph/page.tsx):

import Openjph from "@/components/openjph/open";
import Script from "next/script";

export default async function Page(props) {
  return <>
    <Script
      strategy="beforeInteractive"
      src="/openjphjs.js"
    />
    <Openjph />
  </>
}
  1. Create a client component (e.g., app/components/openjph/open.tsx):
"use client";

import { useEffect } from 'react';

const Openjph = (props) => {
  useEffect(() => {
      try {
        const decoder = new Module.HTJ2KDecoder();
        console.log(decoder);
      } catch (error) {
        console.log(error)
      }
  }, [])
  
  return (
    <>[...more stuff...]</>
  );
};

export default Openjph;

This setup should log the instanced decoder: https://i.sstatic.net/hs8Ub.png

Make sure your tsconfig.json includes paths similar to this:

    "paths": {
      "@/components/*": ["app/components/*"],
    },

Alternatively, you can import the Openjph component using relative paths or any preferred method.

EDIT: If the above code does not work in production builds, here's a workaround for the useEffect hook:

[...]
// @ts-nocheck
[...]
 useEffect(() => {
    try {
      const decoder = new Module.HTJ2KDecoder();
      console.log("has a constructor: ", decoder);
    } catch (error) {
      try {
        console.log("doesn't have a a constructor yet");
        Module.onRuntimeInitialized = async () => {
          const decoder = new Module.HTJ2KDecoder();
          console.log("now it does", decoder);
          const encoder = new Module.HTJ2KEncoder();
          console.log(encoder);
        };
      } catch (error) {
        console.log(error);
      }
    }
  }, []);

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

How to dynamically reference an input textbox ID using javascript or jquery

I have a button titled: GridView1__ctl2_AddButton0 While I can extract the middle part "ctl2" (and variations for each row), I am trying to use it to populate a textbox among many with similar names. GridView1__ctl2_txtStormTimeOn Currently, I could ac ...

Ways to adjust the brightness of any color when hovered over

Is it possible to create a universal effect where an element becomes darker or lighter when hovered over, regardless of the initial color? Here is an example: .change-color{ Background:green; width:100px; height:100px } .change-color:hover{ Background ...

What is the process for animating classes instead of ids in CSS?

My webpage currently features a setup similar to this. function wiggle(){ var parent = document.getElementById("wiggle"); var string = parent.innerHTML; parent.innerHTML = ""; string.split(""); var i = 0, length = string.length; for (i; i ...

Quick fix for obtaining only one response

I'm facing a dilemma where I need to redirect the user to the dashboard page after they log in, but also send their JSON details to my client-side JavaScript. While I know that there can only be one res.send/end/json in a response and dynamic data can ...

Updating a form field dynamically with AJAX in Laravel

I'm working on updating the field $medic->current based on certain logic that I have in mind. I'm quite new to using AJAX and would appreciate a little guidance to kick things off. In my code, I am calculating the difference between two dates ...

Using both Ajax and a standard submit can be applied to a single form in jQuery

I need to implement a confirm step on one of my pages. Here's what I want to achieve: When the user clicks 'submit', an AJAX request is triggered, which performs the necessary action and then displays a confirmation dialog If the user ...

Once an ajax request is made, scripts cease to function correctly

There is a dynamic table on a webpage that I update using ajax. The table contains checkboxes and there are scripts that utilize the checkboxes for certain functionalities, such as toggling the check/uncheck status of all checkboxes when a "Check all / Unc ...

Tips on successfully transferring row data that has been clicked or selected from one adjacent table to another table

Currently, I am facing a challenge with two tables that are positioned next to each other. My goal is to append a selected row from the first table to the second table. After successfully extracting data from the selected row and converting it into an arr ...

Tips for Extracting Real-Time Ice Status Information from an ArcGIS Online Mapping Tool

My goal is to extract ice condition data from a municipal website that employs an ArcGIS Online map for visualization. I want to automate this process for my personal use. While I have experience scraping static sites with Cheerio and Axios, tackling a sit ...

Unveiling the steps to automatically conceal a submitted form in React, no longer requiring the manual activation of a toggle button

Currently, I have a list of songs and a toggle button that reveals a form to add a new song. However, I want the form to hide automatically after submission without requiring another button click. I tried using useEffect but couldn't get it to work. A ...

Locating the source and reason behind the [object ErrorEvent] being triggered

I'm facing an issue where one of my tests is failing and the log is not providing any useful information, apart from indicating which test failed... LoginComponent should display username & password error message and not call login when passed no ...

Using a table row as a counter in HTML

I am looking for a way to automatically assign IDs to table rows using XSLT in a systematic manner. The idea is to have the ID consist of a string followed by a counter, like this: <table> <tr id="Row1"> # it can be only a number => id=" ...

Add a text to the values in a column of a table when the IDs are the same

I am working on a project that involves updating a table based on a data change. The table has a column for ID and when the ID matches a specific variable, I need to append the word 'Updated!' next to it in the table cell. However, the code I hav ...

How to retrieve the value of a table row by clicking with the mouse using jQuery?

I am having an issue with my table data display. Each row in the table is assigned a unique ID, which corresponds to the value of the tr-tag. My goal is to log this ID in the console when a table row is clicked. Here is the table: $.getJSON(`http://local ...

When the tailwind utilities are implemented, they do not appear on the screen

Recently, I embarked on a project using Tailwindcss/Next.js and encountered an issue when trying to apply a box-like shadow to a button with a new utility in pure CSS. Despite my efforts, the changes don't seem to take effect. Can you spot what I migh ...

The postMessage function in my Javascript SlackBot seems to be flooding the channel with messages

I am currently setting up a Slack bot using JavaScript combined with several useful libraries. The main function of this bot is to execute a postMessageToChannel method whenever a user in the channel mentions the specific keyword "help." However, I am fa ...

Customizing the initial search parameters in Vue InstantSearch: A step-by-step guide

I am utilizing the Vue components from Algolia to perform a search on my index. The search functionality is working correctly, but I am curious about setting the initial values for the refinement list upon page load. This is how I have set up the search: ...

The Angular service encounters issues when interacting with REST API

Within my application, a template is utilized: <div class="skills-filter-input" ng-class="{'hidden-xs': skillsFilterHidden}"> <input type="text" ng-model="skillQuery" ng-change="filterSkills()" placeholder="Filter skills" class="filter- ...

Tips for positioning dynamic high charts in a bootstrap row

I have implemented HighCharts for displaying charts on my website. Specifically, I am utilizing the chart type solidgauge. The charts are dynamic and I am looking to arrange them horizontally across the page. My goal is to align the charts in a layout sim ...

Utilize the Webpack library and libraryTarget settings to establish our own custom library as a global variable

I currently have a library named "xyz" that is being imported as a node module from the npm registry. Now, I want to incorporate it as a library and make it accessible under the global name "abc". To achieve this, I plan to utilize webpack configuration. ...