next.js image remotePatterns issue

This is my nextConfig setup. When working on localhost, the remotePatterns configuration in the Next.js Image Component works perfectly fine whether I use environment variables (env) or directly input the URL as a string. However, when I deploy the app to production, the Image Component fails to load the image if I’m using environment variables. If I replace the remotePatterns with a direct string in production, the images display correctly. I have also checked the server logs, and the environment variables seem to contain the correct values. What could be causing this issue?

// nextConfig 
const nextConfig = {
    reactStrictMode: true,
    env: {
        NEXT_PUBLIC_DOMAIN: process.env.NEXT_PUBLIC_DOMAIN,
    },
    async rewrites() {
        return {
            fallback: [
                {
                    source: "/:path*",
                    destination: `${process.env.NEXT_PUBLIC_DOMAIN}/:path*`,
                },
            ],
        };
    },
    images: {
        remotePatterns: [
            {
                protocol: "https",
                hostname: `${process.env.NEXT_PUBLIC_PLATFORM_HOSTNAME}`,
                port: "",
                pathname: `${process.env.NEXT_PUBLIC_API_URL}/image/**`,
            },
        ],
    },
};

module.exports = nextConfig;

// partial file
export const BASE_PLATFORM_IMAGE_SRC = `https://${process.env.NEXT_PUBLIC_PLATFORM_HOSTNAME}${process.env.NEXT_PUBLIC_API_URL}/image/vendor`;

 <Image
    className="rounded-lg object-cover text-white"
    fill // fill container
    src={`${BASE_PLATFORM_IMAGE_SRC}/${id}/publicity/3`}
    alt={t(props.i18n)}
/>

I tried using env to configure remotePatterns, but it doesn’t work correctly.

Will the browser send a new request to the server, so the Server Components re-render, if cookies are set in a Client Component via a Server Action?

In Next.js 15, using React 19, will the browser automatically send a new request to the server, so the Server Components re-render, after cookies are set in a Client Component via a Server Action?

Or is it necessary to manually call router.refresh() from the Client Component?

Is the behavior documented anywhere?

I am getting mixed results in testing and not sure what is going on under the hood.

Why is my Postman returning internal server error when I try to get a mongo schema from this API?

I am trying to make a mock game review website & crud app with next.js and upload it to Vercel.
I’m using the vs plugin postman to check the data on my api but io just get “500 internal server error” am I formatting this wrong or something? I have tested with some basic test code so the routing seems correct.

//app/api/game/route.js
import gameS from "@/models/gameMod";

export async function GET() {
  const categories = await gameS.find().sort({ name: 1 })
  return Response.json(categories)
}

export async function POST(request) {
  const body = await request.json();
  const game = new gameS(body); // Create a new game entry
  await game.save();
  return Response.json(game);
}

export async function PUT(request) {
  const body = await request.json();
  const { _id, ...updateData } = body; // Update game by ID
  const game = await gameS.findByIdAndUpdate(_id, updateData, { new: true });
  if (!game) {
    return new Response("Game not found", { status: 404 });
  }
  return Response.json(game);
}

export async function PATCH(request) {
  const body = await request.json();
  const { _id, ...updateData } = body; // Partial update of game by ID
  const game = await gameS.findByIdAndUpdate(_id, updateData, { new: true });
  if (!game) {
    return new Response("Game not found", { status: 404 });
  }
  return Response.json(game);
}

//models/gameMod.js
import mongoose from "mongoose";

const gameSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    trim: true,
  },
  genre: {
    type: [String], // Array of strings for multiple genres
    required: true,
  },
  releaseDate: {
    type: Date,
    required: true,
  },
  platforms: {
    type: [String], // Array of strings for supported platforms
    required: true,
  },
  developer: {
    type: String,
    required: true,
    trim: true,
  },
  publisher: {
    type: String,
    required: true,
    trim: true,
  },
  rating: {
    type: Number, // For example, 1 to 10
    min: 1,
    max: 10,
  },
  description: {
    type: String,
    trim: true,
  },
  id: { 
    type: mongoose.Schema.Types.ObjectId, 
    ref: "id" 
  },
});

const gameS = mongoose.models.gameSchema || mongoose.model("games", gameSchema);

export default gameS;

I’ve tried GET http://localhost:3000/api/game which I believe translates to curl get http://localhost:3000/api/game
Status 500 internal server error:

<!DOCTYPE html>
<html>

<head>
    <style data-next-hide-fouc="true">
        body {
            display: none
        }
    </style><noscript data-next-hide-fouc="true">
        <style>
            body {
                display: block
            }
        </style>
    </noscript>
    <meta charSet="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <meta name="next-head-count" content="2" />
    <link data-next-font="size-adjust" rel="preconnect" href="/" crossorigin="anonymous" /><noscript
        data-n-css=""></noscript>
    <script defer="" nomodule="" src="/_next/static/chunks/polyfills.js"></script>
    <script src="/_next/static/chunks/webpack.js" defer=""></script>
    <script src="/_next/static/chunks/main.js" defer=""></script>
    <script src="/_next/static/chunks/pages/_app.js" defer=""></script>
    <script src="/_next/static/chunks/pages/_error.js" defer=""></script>
    <script src="/_next/static/development/_buildManifest.js" defer=""></script>
    <script src="/_next/static/development/_ssgManifest.js" defer=""></script><noscript
        id="__next_css__DO_NOT_USE__"></noscript>
</head>

<body>
    <div id="__next"></div>
    <script src="/_next/static/chunks/react-refresh.js"></script>
    <script id="__NEXT_DATA__" type="application/json">
        {"props":{"pageProps":{"statusCode":500}},"page":"/_error","query":{},"buildId":"development","isFallback":false,"err":{"name":"OverwriteModelError","source":"server","message":"Cannot overwrite `games` model once compiled.","stack":"OverwriteModelError: Cannot overwrite `games` model once compiled.n    at Mongoose.model (C:\Users\kevin\TBH5\node_modules\.pnpm\[email protected]\node_modules\mongoose\lib\mongoose.js:608:13)n    at eval (webpack-internal:///(rsc)/./models/gameMod.js:54:134)n    at (rsc)/./models/gameMod.js (C:\Users\kevin\TBH5\.next\server\app\api\game\route.js:72:1)n    at __webpack_require__ (C:\Users\kevin\TBH5\.next\server\webpack-runtime.js:33:42)n    at eval (webpack-internal:///(rsc)/./app/api/game/route.js:8:73)n    at (rsc)/./app/api/game/route.js (C:\Users\kevin\TBH5\.next\server\app\api\game\route.js:62:1)n    at __webpack_require__ (C:\Users\kevin\TBH5\.next\server\webpack-runtime.js:33:42)n    at eval (webpack-internal:///(rsc)/./node_modules/.pnpm/[email protected][email protected][email protected][email protected]/node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fgame%2Frouteu0026page=%2Fapi%2Fgame%2Frouteu0026appPaths=u0026pagePath=private-next-app-dir%2Fapi%2Fgame%2Froute.jsu0026appDir=C%3A%5CUsers%5Ckevin%5CTBH5%5Cappu0026pageExtensions=tsxu0026pageExtensions=tsu0026pageExtensions=jsxu0026pageExtensions=jsu0026rootDir=C%3A%5CUsers%5Ckevin%5CTBH5u0026isDev=trueu0026tsconfigPath=tsconfig.jsonu0026basePath=u0026assetPrefix=u0026nextConfigOutput=u0026preferredRegion=u0026middlewareConfig=e30%3D!:15:98)n    at (rsc)/./node_modules/.pnpm/[email protected][email protected][email protected][email protected]/node_modules/next/dist/build/webpack/loaders/next-app-loader.js?name=app%2Fapi%2Fgame%2Frouteu0026page=%2Fapi%2Fgame%2Frouteu0026appPaths=u0026pagePath=private-next-app-dir%2Fapi%2Fgame%2Froute.jsu0026appDir=C%3A%5CUsers%5Ckevin%5CTBH5%5Cappu0026pageExtensions=tsxu0026pageExtensions=tsu0026pageExtensions=jsxu0026pageExtensions=jsu0026rootDir=C%3A%5CUsers%5Ckevin%5CTBH5u0026isDev=trueu0026tsconfigPath=tsconfig.jsonu0026basePath=u0026assetPrefix=u0026nextConfigOutput=u0026preferredRegion=u0026middlewareConfig=e30%3D! (C:\Users\kevin\TBH5\.next\server\app\api\game\route.js:52:1)n    at __webpack_require__ (C:\Users\kevin\TBH5\.next\server\webpack-runtime.js:33:42)n    at __webpack_exec__ (C:\Users\kevin\TBH5\.next\server\app\api\game\route.js:82:39)n    at C:\Users\kevin\TBH5\.next\server\app\api\game\route.js:83:135n    at __webpack_require__.X (C:\Users\kevin\TBH5\.next\server\webpack-runtime.js:116:21)n    at C:\Users\kevin\TBH5\.next\server\app\api\game\route.js:83:47n    at Object.u003canonymousu003e (C:\Users\kevin\TBH5\.next\server\app\api\game\route.js:86:3)"},"gip":true,"scriptLoader":[]}
    </script>
</body>

</html>

Appending a .docx file to another .docx file in node

I have two files: doc1.docx and doc2.docx

Does anyone know how I can append doc2 to the end of doc1 programmatically? Imagine doc1 is a template front page and doc2 is a page of data. The end product should thus be mergeddoc.docx which looks like doc1 then doc2 aka front page on page 1 and data page on page 2. In word I guess you’d be using the insert tool to add in a document.

I feel like this shouldn’t be hard but I’ve been banging my head against this problem for about three days. If it is a hard problem, does anyone know of a work around? I know you can do this sort of stuff in python but is that the best solution?

Thanks!

I’ve tried to use .docx but it’s not got a merging function
“docx-merger” is basically unsupported and out of date – won’t run for this functionality unless I’m missing something
docx-templates doesn’t work for me either no functionality.

Previous attempt example that doesn’t work:

const fs = require("fs");
const path = require("path");
const os = require("os");
const createReport = require("docx-templates").default;

const saveDocument = (buffer, patientData) => {
  try {
    const downloadsPath = path.join(os.homedir(), "Downloads");
    const filename = `Report_${patientData.forename}_${
      patientData.surname
    }_${Date.now()}.docx`;
    const filePath = path.join(downloadsPath, filename);

    fs.writeFileSync(filePath, buffer);

    return filePath;
  } catch (error) {
    console.error("Error in saveDocument:", error);
    throw error;
  }
};

const generateDocument = async (data) => {
  try {
    console.log("Starting document generation...");

    const selectedGenes = data.selectedGenes;
    const geneData = data.geneData;
    const bloodResults = {
      testDetails: {
        lab: data.bloodsDetails.sendingApplication,
        receivedInLab: data.bloodsDetails.receivingFacility,
        patientId: data.bloodPatientID,
      },
      results: data.bloodResults,
    };
    const basicData = {
      patientData: data.patientData,
      clinician: data.clinicianIdentity,
    };
    const complaints = data.patientComplaints;
    const utilsData = {
      time: data.time,
      geneCount: data.selectedGenes.length,
      countBloodTests: data.bloodResults.length,
    };

    console.log("Data prepared:", {
      selectedGenes,
      geneData,
      bloodResults,
      basicData,
      complaints,
      utilsData,
    });

    const templatePath = path.join(
      __dirname,
      "../templates/base_template.docx"
    );

    if (!fs.existsSync(templatePath)) {
      throw new Error(`Template file not found at path: ${templatePath}`);
    }
    console.log(`Base template found at ${templatePath}`);

    const template = fs.readFileSync(templatePath);

    const dataForTemplate = {
      selectedGenes: [],
      geneData,
      bloodResults,
      basicData,
      complaints,
      utilsData,
    };

    for (const gene of selectedGenes) {
      const geneName = gene.geneName;
      console.log(`Processing gene: ${geneName}`);

      const geneTemplatePath = path.join(
        __dirname,
        "../templates/gene_templates",
        `${geneName}.docx`
      );

      if (!fs.existsSync(geneTemplatePath)) {
        throw new Error(
          `Gene template file not found for gene ${geneName} at path: ${geneTemplatePath}`
        );
      }
      console.log(`Gene template found at ${geneTemplatePath}`);

      const geneTemplateBuffer = fs.readFileSync(geneTemplatePath);

      dataForTemplate.selectedGenes.push({
        ...gene,
        genedoc: geneTemplateBuffer,
      });
    }

    console.log("Data prepared for main template:", dataForTemplate);

    // Generate the final report
    const buffer = await createReport({
      template,
      data: dataForTemplate,
      noSandbox: true, 
      additionalJsContext: {
        INS: (buffer) => ({
          _type: "rawXml",
          xml: buffer.toString("utf8"),
        }),
      },
    });

    console.log("Final report generated.");

    const filePath = saveDocument(buffer, data.patientData);

    console.log(`Document saved at ${filePath}`);

    return `Document generated successfully at ${filePath}`;
  } catch (error) {
    console.error("Error in generateDocument:", error);
    return `Error in generateDocument: ${error.message}`;
  }
};

module.exports = {
  generateDocument,
};

if (require.main === module) {
  (async () => {
    try {
      const data = {
        selectedGenes: [
          { geneName: "COMT", rsCode: "rs6311", combined: "TC" },
        ],
        geneData: {
          COMT: { description: "Catechol-O-methyltransferase gene" },
        },
        bloodsDetails: {
          sendingApplication: "Them",
          receivingFacility: "Us",
        },
        bloodPatientID: "123-4567",
        bloodResults: [
          {
            testCode: "HTR2A",
            testName: "HTR2A Test",
            value: "Positive",
            units: "blahs",
            referenceRange: "",
          },
        ],
        patientData: {
          patientId: "123-4567",
          title: "Mrs",
          forename: "Jane",
          surname: "Doe",
          dob: "1999-01-01",
          sex: "F",
        },
        clinicianIdentity: "Dr Who",
        patientComplaints: [
          "Decreased concentration",
          "Decreased mental sharpness",
        ],
        time: Date.now(),
      };
      const result = await generateDocument(data);
      console.log(result);
    } catch (error) {
      console.error(
        "Error running generateDocument from command line:",
        error
      );
    }
  })();
}

I’ve looked at other answers:
How to append docx file in Golang: wrong language
Using Node’s ‘Docx’ to append to an existing Word doc with JS: explains a limitation in this particular packag
how to append a file using docx package: Same as above.

But I’m not seeing much action for alternate solution that allow this.

Looking for a Web FIle Explorer JS frontend for my backend [closed]

I am looking for some JS frontend for my file manager API backend.

I did some googling but i can not find it myself.

What i have:

REST API for a basic file manager. Operations like folder browse/create/rename/delete , file upload/download/rename/delete
It has oauth2 login support.

I need a frontend build with JS where i could integrate my API so it would be possible to browse folders and edit files/folders.

It can be build with anything, but better something modern (react js, vue. js ?)
And it must be licensed for free (the project is just a demo)

Can you recommend something?

How can i convert this NBT data string to a valid native javascript object or JSON, and why can the chrome console do it?

So i’m trying to get it so you can export NBT data from minecraft so it can be used in this online tool i’m making. Here is an example of the NBT data I am trying to convert:

const NbtString = "{ForgeCaps:{},Items:[{Count:1b,Slot:0b,id:"the_vault:card",tag:{data:{entries:[{colors:["RED"],groups:["Utility","Stat","Essence"],model:"the_vault:card/icon/mana_regeneration#inventory",modifier:{config:{attribute:"the_vault:mana_regen",maxTier:5b,pool:[{config:'{"min":0.01,"max":0.01,"step":0.01}',tier:1b},{config:'{"min":0.02,"max":0.02,"step":0.01}',tier:2b},{config:'{"min":0.03,"max":0.03,"step":0.01}',tier:3b},{config:'{"min":0.04,"max":0.04,"step":0.01}',tier:4b},{config:'{"min":0.05,"max":0.05,"step":0.01}',tier:5b}]},type:"gear",values:[{tier:1b,value:0.01f},{tier:2b,value:0.02f},{tier:3b,value:0.03f},{tier:4b,value:0.04f},{tier:5b,value:0.05f}]},name:'{"text":"Mana Regeneration Card"}'}],tier:1b}}},{Count:1b,Slot:1b,id:"the_vault:card",tag:{data:{entries:[{colors:["RED","GREEN","BLUE"],groups:["Wild","Stat","Temporal","Resource","Arcane","Evolution"],modifier:{config:{maxTier:1b},type:"dummy"},name:'{"text":"Blue Wild Card"}'}],tier:1b}}},{Count:1b,Slot:2b,id:"the_vault:card",tag:{data:{entries:[{colors:["BLUE"],condition:{config:{tiers:[{pool:[{filters:[{colorFilter:[{value:["GREEN"],weight:1b},{value:["BLUE"],weight:1b},{value:["YELLOW"],weight:1b},{value:["RED"],weight:1b}],groupFilter:[{value:["Stat"],weight:1b},{value:["Resource"],weight:1b},{value:["Evolution"],weight:1b}],minCount:{max:10b,min:7b,type:"uniform"},neighborFilter:[{weight:100b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[{value:["GREEN"],weight:1b},{value:["BLUE"],weight:1b},{value:["YELLOW"],weight:1b},{value:["RED"],weight:1b}],groupFilter:[{value:["Stat"],weight:1b},{value:["Resource"],weight:1b},{value:["Evolution"],weight:1b}],minCount:{max:4b,min:3b,type:"uniform"},neighborFilter:[{value:["ROW"],weight:1b},{value:["COLUMN"],weight:1b},{value:["DIAGONAL"],weight:1b},{value:["ADJACENT"],weight:1b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[{weight:1b}],groupFilter:[{value:["Arcane"],weight:1b}],maxCount:{max:3b,min:1b,type:"uniform"},neighborFilter:[{weight:1b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[{weight:1b}],groupFilter:[{value:["Stat"],weight:1b},{value:["Resource"],weight:1b},{value:["Evolution"],weight:1b}],maxCount:{max:6b,min:4b,type:"uniform"},minCount:{max:2b,min:1b,type:"uniform"},neighborFilter:[{weight:1b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[{value:["GREEN"],weight:1b},{value:["BLUE"],weight:1b},{value:["YELLOW"],weight:1b},{value:["RED"],weight:1b}],groupFilter:[{weight:1b}],maxCount:{max:6b,min:4b,type:"uniform"},minCount:{max:2b,min:1b,type:"uniform"},neighborFilter:[{weight:1b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[{weight:1b}],groupFilter:[{weight:1b}],maxCount:{max:2b,min:1b,type:"uniform"},neighborFilter:[{value:["ROW"],weight:1b},{value:["COLUMN"],weight:1b},{value:["DIAGONAL"],weight:1b},{value:["ADJACENT"],weight:1b}],tierFilter:[]}],weight:1b}],tier:1b}]},filters:[{tier:1b,value:[{maxCount:1b,neighborFilter:["COLUMN"]}]}]},groups:["Offensive","Arcane"],model:"the_vault:card/icon/ice_blast#inventory",modifier:{config:{attribute:"the_vault:added_ability_level",maxTier:1b,pool:[{config:'{"abilityKey":"Ice_Bolt_Blast","levelChange":1}',tier:1b}]},type:"gear",values:[{tier:1b,value:{ability:"Ice_Bolt_Blast",levelChange:1}}]},name:'{"text":"Glacial Blast Card"}'}],tier:1b}}},{Count:1b,Slot:3b,id:"the_vault:card",tag:{data:{entries:[{colors:["GREEN"],groups:["Utility","Scaling"],model:"the_vault:card/icon/healing_efficiency#inventory",modifier:{config:{attribute:"the_vault:healing_effectiveness",maxTier:5b,pool:[{config:'{"min":0.002,"max":0.002,"step":1.0}',tier:1b},{config:'{"min":0.004,"max":0.004,"step":1.0}',tier:2b},{config:'{"min":0.006,"max":0.006,"step":1.0}',tier:3b},{config:'{"min":0.008,"max":0.008,"step":1.0}',tier:4b},{config:'{"min":0.01,"max":0.01,"step":1.0}',tier:5b}]},type:"gear",values:[{tier:1b,value:0.002f},{tier:2b,value:0.004f},{tier:3b,value:0.006f},{tier:4b,value:0.008f},{tier:5b,value:0.01f}]},name:'{"text":"Scaling Healing Efficiency Card"}',scaler:{config:{tiers:[{pool:[{filters:[{colorFilter:[{value:["GREEN"],weight:1b},{value:["BLUE"],weight:1b},{value:["YELLOW"],weight:1b},{value:["RED"],weight:1b}],groupFilter:[],neighborFilter:[{value:["ROW"],weight:5b},{value:["COLUMN"],weight:5b},{value:["DIAGONAL"],weight:3b},{value:["ADJACENT"],weight:5b},{value:["SURROUNDING"],weight:1b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[{value:["GREEN"],weight:1b},{value:["BLUE"],weight:1b},{value:["YELLOW"],weight:1b},{value:["RED"],weight:1b}],groupFilter:[{value:["Stat"],weight:1b},{value:["Evolution"],weight:1b},{value:["Resource"],weight:1b}],neighborFilter:[{value:["ROW"],weight:5b},{value:["COLUMN"],weight:5b},{value:["DIAGONAL"],weight:3b},{value:["ADJACENT"],weight:5b},{value:["SURROUNDING"],weight:1b}],tierFilter:[]}],weight:1b},{filters:[{colorFilter:[],groupFilter:[{value:["Stat"],weight:1b},{value:["Evolution"],weight:1b},{value:["Resource"],weight:1b}],neighborFilter:[{value:["ROW"],weight:5b},{value:["COLUMN"],weight:5b},{value:["DIAGONAL"],weight:3b},{value:["ADJACENT"],weight:5b},{value:["SURROUNDING"],weight:1b}],tierFilter:[]}],weight:1b}],tier:1b}]},filters:[{tier:1b,value:[{colorFilter:["GREEN"],groupFilter:["Evolution"],neighborFilter:["SURROUNDING"]}]}]}}],tier:1b}}},{Count:1b,Slot:4b,id:"the_vault:card",tag:{data:{entries:[{colors:["GREEN"],groups:["Resource"],model:"the_vault:vault_plating#inventory",modifier:{config:{count:[{roll:{max:8b,min:3b,type:"uniform"},tier:1b}],highlightColor:65280,loot:[{item:"the_vault:vault_plating",weight:1.0d}],maxTier:1b,task:"@easy",tooltip:'{"color":"gold","extra":[{"color":"#FFFFFF","text":"${count}"},{"color":"yellow","text":" Vault Plating "},{"text":"${task}"}],"text":"+"}'},counts:[{count:7b,tier:1b}],task:{children:[],config:{filter:"@the_vault:living"},counter:{baseTarget:7b,config:{target:{max:7b,min:6b,type:"uniform"},variables:{targetTierContribution:1b}},current:0b,target:7b,type:"target"},operating:0b,renderer:{tooltip:'{"text":"per ${target} Living Chests looted"}',type:"card"},type:"loot_chest"},type:"task_loot",uuid:[I;-1335797438,959268282,-1831723904,956595013]},name:'{"text":"Vault Plating Card"}'}],tier:1b}}}],id:"quark:variant_chest",x:-317,y:112,z:473}"

That comes straight from Minecrafts “/data get” command.

I’ve created this function which fixes a lot of things already:

function parseNBT(data) {
    return data
        // Convert "1b", "2b", etc., to plain integers (byte to int)
        .replace(/(d+)b/g, '$1')

        // Convert "1.0f", "0.2f", etc., to plain numbers (float to number)
        .replace(/(d*.?d+)f/g, '$1')

        // Convert "1.0d", "0.5d" (double) to plain numbers
        .replace(/(d*.?d+)d/g, '$1')

        // Handle "uuid:[I;...]" - Convert to valid JSON array
        .replace(/uuid:[I;([d,-]+)]/g, function (match, p1) {
            return `"uuid": [${p1}]`;
        })
}

I can actually put the string that that function returns inside a variable in the chrome console and the chrome console will parse it as an object.

But within my code i think i can only use JSON.parse and it needs to be formatted as JSON in that case. But that is where things get messy, because of the following reasons:

  • values with colons in them like “the_vault:card” or “quark:variant_chest”. The usual way to put quotation marks is to find colons, but in this case that messes things up.

  • nested stuff like this part: pool:[{config:'{“min”:0.01,”max”:0.01,”step”:0.01}’,tier:1b},{config:'{“min”:0.02,”max”:0.02,”step”:0.01}’,tier:2b},{config:'{“min”:0.03,”max”:0.03,”step”:0.01}’,tier:3b},{config:'{“min”:0.04,”max”:0.04,”step”:0.01}’,tier:4b},{config:'{“min”:0.05,”max”:0.05,”step”:0.01}’,tier:5b}]

I’ve got two questions:

  1. How does the chrome console does it? Is there anyway to do it in the same way the chrome console does it?
  2. If not, can someone help me with how to fix all the issues that arise when trying to format the string to correct JSON?

If you need any more information, please let me know.

i want to print an element in the bottom of the last page of my certification

Hello there I have certification system management and I want to show a footer or a section at the bottom of my page, I tried to fix the section but it shows in time I tried some javascript codes but it still gave me the problem so how can I resolve this problem?

.signature {
  left: 0;
  right: 0;
  bottom: 2cm;
  display: flex;
  padding: 0 1cm;
  justify-content: space-between;
  position: fixed;
}
  <div class="signature">
    <h2>پ.هـ.د. نه‌به‌ز ابراهیم محمد</h2>
    <p>هاریكارێ سه‌رۆكێ زانكویێ بۆ كاروبارێن قوتابیان</p>
  </div>
  <div>
    <h2>ديار هاشم مالو</h2>
    <p>توماركارێ زانكویێ</p>
  </div>
</section>

next-themes attribute=’class’ not working in Next.js 14

I have used next-themes several times but this time the attribute='class' is not working, I tried to use everything that I could find over internet.

//environment
"next": "14.2.12",
"next-themes": "^0.3.0",

This is my current setup:

'use client';

import * as React from 'react';
import { Moon, Sun } from 'lucide-react';
import { useTheme } from 'next-themes';

import {
  Button,
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui';

export function ThemeSwitcher() {
  const { setTheme } = useTheme();
  const [mounted, setMounted] = React.useState(false);

  React.useEffect(() => {
    setMounted(true);
  }, []);

  if (!mounted) {
    return null;
  }

  function handleChange(theme: string) {
    setTheme(theme);
    // document.documentElement.className = theme;
  }

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <Button
          className="md:bg-transparent md:border-0 md:hover:bg-transparent md:hover:text-white/80"
          variant="outline"
          size="icon-sm"
        >
          <Sun className="h-[1.2rem] w-[1.2rem] rotate-0 scale-100 transition-all dark:-rotate-90 dark:scale-0" />
          <Moon className="absolute h-[1.2rem] w-[1.2rem] rotate-90 scale-0 transition-all dark:rotate-0 dark:scale-100" />
          <span className="sr-only">Toggle theme</span>
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem onClick={() => handleChange('light')}>
          Light
        </DropdownMenuItem>
        <DropdownMenuItem onClick={() => handleChange('dark')}>
          Dark
        </DropdownMenuItem>
        <DropdownMenuItem onClick={() => handleChange('system')}>
          System
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

I have tried to change the class by using document but on page refresh the theme is reset to default.

import React from 'react';
import { ThemeProvider } from 'next-themes';

interface ThemeProps {
  readonly children?: React.ReactNode;
}

const Theme: React.FC<ThemeProps> = ({ children }) => {
  return (
    <ThemeProvider
      attribute="class"
      defaultTheme="light"
      enableSystem
      disableTransitionOnChange
    >
      {children}
    </ThemeProvider>
  );
};

export { Theme };

All the other attributes like data-theme and color-scheme are getting updated, but I want to use class to change themes :/

In my diagnosis, the attribute is not working at all, I tried to change it to data-mode, class but it just keeps it as data-theme.
Let me know if I am doing something wrong here.

useTemplateRef is not reactive for arrays?

I’d like to react to changes made to an array of template ref elements created with a v-for loop over some collection of arbitrary objects.

The docs provide a way to save these elements to an array: https://vuejs.org/guide/essentials/template-refs.html#refs-inside-v-for

I’ve modified the provided example to see, if the resulting itemsRef array would be reactive. The code is:

<script setup>
import { ref, useTemplateRef, watch, markRaw } from 'vue'

const list = ref([1, 2, 3])

const itemRefs = useTemplateRef('items')

watch(itemRefs, () => {
  console.log("itemsRef:", itemRefs.value.length);
}, {deep: true});

watch(list, () => {
  console.log("list:", list.value.length, itemRefs.value.length);
}, { deep: true });
</script>

<template>
  <button @click="list.push(list.length + 1)">add</button>
  <ul>
    <li v-for="item in list" ref="items">
      {{ item }}
    </li>
  </ul>
</template>

But the return value of useTemplateRef seems to be a ShallowRef, judging from its TypeScript signature:

function useTemplateRef<T>(key: string): Readonly<ShallowRef<T | null>>

So the watch on list really runs just once:

shallow ref

As you can see, array’s contents are changing, but they are not captured by vue. I tried making the watch deep, but it does not help.

Is there a way to make the ref not shallow somehow? Or maybe there is another way?

const { createApp, ref, useTemplateRef, watch, markRaw } = Vue;

const app = createApp({
  setup() {
    const list = ref([1, 2, 3]);

    const itemRefs = useTemplateRef('items');

    watch(itemRefs, () => {
      console.log("itemsRef: ", itemRefs.value.length);
    }, { deep: true });

    watch(list, () => {
      console.log("list: ", list.value.length, itemRefs.value.length);
    }, { deep: true });
    
    return { list }
  }
});

app.mount('#app');
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>

<div id="app">
  <button @click="list.push(list.length + 1)">add</button>
  <ul>
    <li v-for="item in list" ref="items">
      {{ item }}
    </li>
  </ul>
</div>

anchor works around padding of text but not on the text Itself [closed]

I have a problem where i have created <li><a>...</a></li> elements so that I if a person clicks they can be redirected to a page. The problem is, If a click on the padding around the text, the anchor works perfectly fine. However, if i were to hover over the text directly and click, then the anchor fails to work. What seems to be the problem here.

I wanted so that If I were to click the text inside the <li> element, the clicking would take me to another page, However, it doesn’t work like that, I have tried moving the anchor elements outside the list element but still it doesn’t work.

Interestingly however, the last <li><a>...</a></li> I have, works perfectly (for instance the a:hover works, and the clicking works as well) even though nothing is different; all the syntax are the same.

body {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  height: 100%;
  margin: 0;
  overflow-x: hidden;
  font-family: Verdana, Geneva, Tahoma, sans-serif;
  padding: 0;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
}

header>ul>li>a {
  user-select: none;
  text-decoration: none;
  color: black;
  font-size: 17px;
  padding: 0;
  margin: 0;
}

header>ul>li {
  cursor: pointer;
}

header>ul>li>a:hover {
  cursor: pointer;
  color: rgb(108, 6, 152);
  transition: 0.1s;
}

.car-header {
  text-decoration: none;
  cursor: pointer;
}

.car-header:hover {
  background-color: rgba(24, 1, 43, 0.932);
  letter-spacing: 4px;
  border-radius: 5px;
  color: white;
  padding: 5px;
  transition: 0.1s;
  margin-left: -12px;
}

.car-header:checked {
  background-color: antiquewhite;
  border-radius: 5px;
  padding: 5px;
}

.car-types {
  cursor: pointer;
  pointer-events: auto;
}

.car-types-choose>button {
  border: none;
  border-radius: 10px;
  width: 90%;
  height: 50px;
  background-color: white;
  font-size: 18px;
  cursor: pointer;
}

.car-types-choose>button:hover {
  background-color: rgb(241, 241, 241);
}

.car-types-choose {
  display: none;
  transition: 0.1s;
  padding: 10px;
  inset: unset;
  opacity: 0;
  position: absolute;
  border: none;
  border-radius: 5%;
  width: 200px;
  height: 1px;
  background-color: rgba(1, 10, 10, 0.772);
  top: 45px;
  right: 158px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  row-gap: 10px;
}

.text-control {
  text-align: center;
  max-height: 230px;
}

.one-car:hover {
  cursor: pointer;
  box-shadow: 5px 5px 20px 10px rgba(74, 71, 71, 0.269);
  transition: 0.2s;
}

header {
  padding: 0px 40px 5px 40px;
  align-items: center;
  text-align: center;
  width: 100%;
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
}

header>p {
  font-size: large;
  font-weight: bold;
}

header>ul {
  display: flex;
  gap: 20px;
  list-style-type: none;
}

.outer-box {
  display: flex;
  flex-wrap: wrap;
  flex-direction: row;
  width: 70%;
  min-height: 500px;
  justify-content: space-between;
  align-items: center;
  row-gap: 20px;
  margin-bottom: 20px;
}
<header>
  <p><a class="car-header">CARS</a></p>
  <ul>
    <li class="js-car-types">Vehicles</li>
    <li><a href="Questions.html">Questions</a></li>
    <li><a href="Questions.html">Plans and Pricing</a></li>
  </ul>
</header>
<div class="car-types-choose js-car-types-choose">
  <button class="Car">All Vehicles</button>
  <button class="Racecars">RaceCars</button>
  <button class="Civilian">Civilian</button>
</div>
<div class="outer-box js-outer-box">

</div>
<script src="../Car-data/data.js" type="module"></script>
<script src="../scripts/front-page.js" type="module"></script>

How to Integrate ReactJs or NextJs Microfrontend components in non React App

  • Lets say if I create microfrontend components using React Vite
    App
    by using plugin vite-module-federation…

    • Now consumption of these components is very easy if I consume it in
      my Host Microfrontend App which also built with React Vite App
      using vite-module-federation
  • Lets say if I create microfrontend components using NextJs by using plugin Next Module Federation

    • Now consumption of these components is very easy if I consume it in
      my Host Microfrontend App which also built with NextJs
      using Next Module Federation

But my use-case is different I want to integrate those components in
non-react App e.g Vanilla JS Project, Yii Framework View, Laravel
Framework

Below is the config file of my React Vite App

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import federation from '@originjs/vite-plugin-federation';

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react(),
    federation({
      name: 'todo-components',
      filename: 'remoteEntry.js',
      exposes: {
        './List': './src/components/List',
        './Input': './src/components/Input',
      },
      shared: ['react', 'react-dom'],
    }),
  ],
  build: {
    modulePreload: false,
    target: 'esnext',
    minify: false,
    cssCodeSplit: false,
  },
});

But I’m not able to extract components, from remoteEntry.js file, if I want to integrate components, lets say in VanillaJs project

I’m just pasting below Scripts tag, you can assume there is a Div container with id=’react-root’

    <!-- React and ReactDOM CDN -->
    <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

    <!-- remoteEntry.js bundle downloading -->
    <script type="module" src="http://localhost:4173/assets/remoteEntry.js"></script>
    

    <!-- Got Below Snippet From ChatGPT -->
    <!-- Trying to Extract Component, But getting error on get -->
    <script>
         (async () => {
             const module = await window['todo-components'].get('./Input');
             const MyReactComponent = module.default;
             const rootElement = document.getElementById('react-root');
             ReactDOM.render(
             React.createElement(MyReactComponent, { prop: 'value' }), rootElement);
         })();
    </script>

Highcharts xranges draw on wrong y value

I am encountering unexpected behavior when drawing additional xranges on my Highchart to single x- and y-axis.

Upon initial start of dragging the xrange, I want hypothetical drop spots for the dragged xrange to appear.

Upon drop, I want the xrange to jump to the hypothetical drop point closest to the actual drop point and the hypothetical drop spots to disappear.

I am trying to achieve this by temporarily drawing additional xranges at the values for those hypothetical drop spots, which I am again removing upon drop.

I would expect the newly added xranges to appear right on the tick of their assign y-value. However, they appear to have an offset of a few decimal points (same with the updated y-value of the initial xrange in the example below – it somehow works in my actual project though).

To replicate, run the code below and drag & drop the xrange.

(Line series can be ignored, just placed it there to fix the ranges.)

const ghosts = [1, 2, 3, 4, 5];

const chart = Highcharts.chart('container', {
    legend: {
        enabled: false
    },
    series: [{
    type: 'line',
    data: [
        [0, 0],
      [1, 1],
      [2, 2],
      [3, 3],
      [4, 4],
      [5, 5],
      [6, 6]
    ]
  }],
  chart: {
    events: {
      load: function() {
        addXRange(this);
      }
    }
  }
});

function addXRange(chart) {
    chart.addSeries({
        type: 'xrange',
        pointWidth: 3,
        threshold: null,
        data: [{
            x: 1,
            x2: 5,
            y: 3,
            draggableY: true
        }],
        dragDrop: {
            draggableY: true
        },
        point: {
            events: {
                dragStart: function(e) {
                    addGhosts(chart, ghosts);
                },
                drop: function(e) {
                    const dropPoint = e.target.options.y;
                    const closestGhost = ghosts.reduce((prev, curr) =>
                        Math.abs(curr - dropPoint) < Math.abs(prev - dropPoint) ? curr : prev
                    );
                    deleteGhosts(chart);
                    this.update({
                        y: closestGhost
                    });
                    chart.redraw(false);
                }
            }
        }
    });
}

function addGhosts(chart, ghosts) {
    const className = 'ghostClass';

    ghosts.forEach(function(ghost) {
        chart.addSeries({
            type: 'xrange',
            pointWidth: 3,
            threshold: null,
            className: className,
            data: [{
                x: 1,
                x2: 5,
                y: ghost
            }]
        });
    });
}

function deleteGhosts(chart) {
    const className = 'ghostClass';

    for (let i = chart.series.length - 1; i >= 0; i--) {
        if (chart.series[i].options.className === className) {
            chart.series[i].remove(false, false);
        }
    }
}
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/xrange.js"></script>
<script src="https://code.highcharts.com/modules/draggable-points.js"></script>

<div id="container"></div>

Tesseract.js OCR not recognizing text accurately on reflective surfaces

I’m using Tesseract.js to extract text from an HTML canvas (loaded throught camera). I’m having issues when the text is printed on reflective surfaces, as Tesseract frequently fails to detect the correct characters.

// Process text detection from the cropped canvas using Tesseract OCR
const processTextFromCanvas = (croppedCanvas) => {
  Tesseract.recognize(croppedCanvas.toDataURL(), "eng").then(({ data }) => {
    const detectedText = data.text.replace(/s/g, "").replace(/n/g, "");
    const textMatch = detectedText.match(/[A-Za-z0-9]{5,}/); // Search for alphanumeric text of length 5 or more

    if (textMatch) {
      detectedTextField.value = textMatch[0];
      stopCamera();
    }
  });
};

Issues:

Tesseract frequently fails to accurately recognize text when it’s printed on reflective or shiny surfaces.

The OCR result often includes extra characters or is incomplete.

Questions:

Are there any specific Tesseract.js settings or image pre-processing techniques I can use to improve accuracy, especially for reflective surfaces?

Would training a custom model for Tesseract be necessary in this case?
Is there a better alternative OCR engine that could handle these types of conditions?

Any help or advice on improving this OCR process would be greatly appreciated.

How JS Engine knows whether there is a callback waiting to get executed?

From what I know, When there is an setTimeout, timer webAPI is called and once the timer finishes, the callback will be pushed to callback queue.
once the call stack is empty, event loop picks up the message from callback queue and executes.

If setTimeout is of 1 hour and call stack is empty as it finishes executing the global execution context. Now there won’t be any call back function in callback queue as it will pushed to queue once after timer API finishes (1 hour). Event loop checks the call stack whether it is empty and even in call back queue it will empty. How JS engine waits for 1 hour?

How js engine keeps track of call back function that are not in call back queue.

How to implement on-the-fly decryption with a Node.js video stream server?

I am working on an LMS app with Electron.js. I want to secure the video content put on that LMS while being available to played offline. So, I thought of encrypting the video files (using AES-256-CBC) and let the students download and play them through the app. Of course, they won’t be able to play the videos outside the app since it’s encrypted.

The issue here is that I have the video stream server working fine with normal mp4 files. However, when I try to pipe the read stream to dicipher before piping to response, it doesn’t work.
I have been playing around the issue for a couple of hours. Sometimes I got WRONG_FINAL_BLOCK_LENGTH, others BAD_DECRYPT, …etc.

Can you please help integrate the decryption with this video streaming server ?

Also, if you have any recommendations for this scenario better than this strategy, please do 🙂

This is the function initiating the video stream server.

import { createDecipheriv } from "crypto";
import { IpcMainInvokeEvent } from "electron";
import { createReadStream, statSync } from "fs";
import { createServer } from "http";

function startVideoServer(_event: IpcMainInvokeEvent, encryptedFilePath: string) {
    encryptedFilePath = "C:\Users\mikha\AppData\Roaming\dr-youssef-nagah\videos\contentProtected.mp4.enc"; // Just for testing now

    return new Promise((resolve, reject) => {
        const server = createServer((req, res) => {
            const decipher = createDecipheriv(
                "aes-256-cbc",
                Buffer.from("key_here_ofc", "hex"),
                Buffer.from("iv_here_too", "hex")
            );
            const input = createReadStream(encryptedFilePath);

            // Get file size
            const stats = statSync(encryptedFilePath);
            const fileSize = stats.size;
            const BLOCK_SIZE = 16; // AES block size

            // Handle range requests
            const range = req.headers.range;
            if (range) {
                const CHUNK_SIZE = 10 ** 6; // 1MB chunk size
                let start = Number(range.replace(/D/g, ""));
                let end = Math.min(start + CHUNK_SIZE, fileSize - 1);

                const contentLength = end - start + 1;
                const headers = {
                    "Content-Range": `bytes ${start}-${end}/${fileSize}`,
                    "Accept-Ranges": "bytes",
                    "Content-Length": contentLength,
                    "Content-Type": "video/mp4",
                };

                res.writeHead(206, headers);

                const stream = createReadStream(encryptedFilePath, { start, end });

                stream.pipe(res);

                // Handle stream errors properly
                stream.on("error", (error) => {
                    console.error("Stream error:", error);
                    if (!res.headersSent) {
                        res.writeHead(500, { "Content-Type": "text/plain" });
                    }
                    res.end();
                });

                // Ensure streams close properly when finished
                decipher.on("end", () => {
                    if (!res.writableEnded) {
                        res.end();
                    }
                });
            }

            // Handle errors
            input.on("error", (error) => {
                console.error("File read error:", error);
                res.writeHead(500);
                res.end("Error reading video");
                reject(error);
            });

            decipher.on("error", (error) => {
                console.error("Decryption error:", error);
                res.writeHead(500);
                res.end("Error decrypting video");
                reject(error);
            });
        });

        server.listen(0, "127.0.0.1", () => {
            const port = server.address()?.port;
            console.log(`Video server is running at http://127.0.0.1:${port}`);
            resolve(JSON.stringify({ port, server }));
        });
    });
}

export default startVideoServer;

Also, this is the function I have used to encrypt the video file.

import { createCipheriv } from "crypto";
import { createReadStream, createWriteStream } from "fs";

function encryptFile(filePath: string, encryptedPath: string, secretKey: string, iv: string) {
    const cipher = createCipheriv("aes-256-cbc", Buffer.from(secretKey, "hex"), Buffer.from(iv, "hex"));
    const input = createReadStream(filePath);
    const output = createWriteStream(encryptedPath);

    input.pipe(cipher).pipe(output);

    output.on("finish", () => {
        console.log("File encrypted successfully.");
    });
}

Appreciate any help! TIA 🙂