Nexu’s certificate download and QR generation are entirely client-side operations. No server function is invoked, and no file is uploaded to Firebase Storage during download. The PDF is built by capturing a live DOM node as an image and embedding it into an A4 landscape document — all inside the user’s browser.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Stivenz3/Nexu/llms.txt
Use this file to discover all available pages before exploring further.
Certificate HTML Template: CertificateDocument
The visual certificate is rendered by src/components/certificate/CertificateDocument.tsx. The root <div> is given a stable DOM ID:
CertificateOfficialPage imports this constant and passes it to the PDF download function so the two are always in sync — there is no hardcoded string on the call site.
The component renders:
- Course name, “Certificado de Aprobación” heading, and the Nexu award icon
- Holder’s full name and document string
- A table of approved modules (
completedLessons) with per-lesson scores - Verification code, average score, issue date, and expiry date
- A signature block referencing Resolución 2674 de 2013
- The QR code image (generated asynchronously, see below)
PDF Generation: downloadCertificatePdf
- Looks up
document.getElementById(elementId)— throws if the node is absent. - Calls
html2canvas(element, { scale: 2, useCORS: true, backgroundColor: '#ffffff' })to render the DOM node to a<canvas>at 2× resolution. - Converts the canvas to a PNG data URL.
- Creates a
jsPDFinstance with{ orientation: 'landscape', unit: 'mm', format: 'a4' }. - Calculates centered placement with an 8 mm margin, preserving the canvas aspect ratio.
- Calls
pdf.addImage(...)thenpdf.save(fileName)to trigger the browser download.
CertificateOfficialPage):
ActionsCard component inside CertificateOfficialPage:
QR Code Generation
The QR is generated with theqrcode npm package directly in the browser. CertificateDocument runs this effect whenever certificate.qrVerifyUrl changes:
<img> tag inside the certificate. Because it is part of the DOM at the time html2canvas runs, it is captured in the PDF automatically.
Verification URL: buildVerifyUrl
The QR code encodes a URL assembled by src/lib/verifyUrl.ts:
- In the browser: uses
window.location.origin(the current domain). - Outside the browser (SSR/build-time): falls back to the
VITE_APP_URLenvironment variable, then tohttps://nexu.vercel.app.
Certificate Pages
| Route | Page | Purpose |
|---|---|---|
/certificado | CertificatePage | Shows course progress, per-lesson competency list, and a link to the official certificate once all 8 lessons are passed |
/certificado/documento | CertificateOfficialPage | Shows CertificateDocument, the PDF download button, and the shareable verification link |
CertificatePage uses fetchCourseCertificationProgress and getCourseCertificate to decide what to render. CertificateOfficialPage guards access: if not all lessons are passed, it shows a “Certificado no disponible” state (or a demo download if the first two lessons are passed).
npm Dependencies
| Package | Purpose |
|---|---|
jspdf | Creates the PDF file and handles A4 landscape formatting |
html2canvas | Captures the certificate DOM node as a pixel-accurate PNG |
qrcode | Generates the QR code as a data URL image |
Phase 2 — Firebase Storage upload: PDF upload to Firebase Storage is not implemented today. In a future iteration,
downloadCertificatePdf (or a Cloud Function) will upload the generated PDF to Firebase Storage and persist the download URL in certificates/{certificateId}. For now, the PDF is generated and downloaded on demand entirely in the browser without any Storage interaction.