Closed MikeCarbone closed 4 weeks ago
Hi @MikeCarbone, are you trying to render it on the client or server component? Have you seen this example https://github.com/kozakdenys/qr-code-styling-examples/tree/master/examples/nextjs/src/app? Maybe it will give you some hints.
Yes, I've seen it. I think my use case is a bit different because I use the Next.js API route to return the image buffer instead of rendering it. I think the Node example is more fitting considering this.
Here is the full code:
import { NextApiRequest, NextApiResponse } from 'next';
import { QRCodeStyling } from "qr-code-styling/lib/qr-code-styling.common.js";
import nodeCanvas from "canvas";
import { JSDOM } from "jsdom";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'GET') {
return res.status(405).json({ message: 'Method Not Allowed' });
}
const { id } = req.query;
if (!id || typeof id !== 'string') {
return res.status(400).json({ message: 'Invalid or missing ID' });
}
const host = req.headers.host;
const protocol = req.headers['x-forwarded-proto'] || 'http'; // to handle HTTPS in production
const trademarkUrl = "https://heykiwi-images-prod.s3.us-east-2.amazonaws.com/images/1WZPT6QPNBXCSQQ.png";
// console.log(trademarkUrl);
try {
const options = {
width: 1024,
height: 1024,
data: `${protocol}://${host}/go/${id}`,
image: trademarkUrl,
type: "png",
dotsOptions: {
color: "#212121",
type: "square"
},
backgroundOptions: {
color: "#ffffff",
},
qrOptions: {
errorCorrectionLevel: "H"
},
imageOptions: {
hideBackgroundDots: true,
imageSize: 0.1,
saveAsBlob: true,
crossOrigin: "anonymous",
margin: 1
}
}
const qrCodeImage = new QRCodeStyling({
jsdom: JSDOM,
nodeCanvas, // this is required
...options,
});
const buffer = await qrCodeImage.getRawData("png");
// Send the QR code as an image
res.setHeader('Content-Type', 'image/png');
// res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
res.send(buffer);
} catch (err) {
console.error(err);
res.status(500).send('Error generating QR code');
}
}
And here is the rendered QR:
The problem is, the QR is successfully generated but the image is not rendered in the middle. The margin and space for the image is rendered, however. I can't figure out how I can debug this further.
@MikeCarbone have you tried const buffer = await qrCodeImage.getRawData("svg");
it might be easier to debug, as you will see the image element and source were used for it.
png
is generated based on svg
with the help of canvas.
This is a good lead, trying this! I was able to get the image within the QR in production. However the SVG return seems to be inconsistent. Sometimes returns correctly, sometimes it returns an SVG with nothing inside of it. Going to keep digging...
@MikeCarbone cool, keep me updated 🙏 If you can reproduce this issue in some service with public access (codesandbox or something) I can try to investigate too.
Everything seems to be working now. Switching to SVG output now consistently renders the image inside
I'm not sure what the issue is with outputting PNG... however, gotta move on for now. Thanks for the help @kozakdenys !
@kozakdenys I think node-canvas isn't rendering the center image pngs correctly. I tried with various pngs (512x512, 1024x1024 sizes) encoded as data Uri and all of them ended up as a black box. I think you should probably take a look at that part of the code. I tried with both the current version of node-canvas and node-canvas v3 RC and they are all giving the same result.
Hi @kozakdenys
I have similar issue that I manage to reproduce every time, this seems to be only happen if:
getRawData('png')
Hey @kozakdenys ,
is there a way I can debug image loading in production? For some reason the image doesnt render in production, even though nothing changes between local and hosted. There are no errors being produced and the QR generation succeeds without failure.
Is there a way I can log an issue if image fetch fails?
Hosted on Railway, Next.js API route using pages router
image URL:
https://heykiwi-images-prod.s3.us-east-2.amazonaws.com/images/1WZPT6QPNBXCSQQ.png
Wrapped in a try/catch but no error is produced.
Mike