Overview
VCVerifier provides a customizable login page at /api/v1/loginQR that displays a QR code for wallet-based authentication. You can customize the appearance and behavior by providing custom HTML templates and static assets.
Template Directory Structure
Templates and static files are organized as follows:
views/
├── verifier_present_qr.html # Main login template (required)
└── static/ # Static assets directory
├── css/
│ └── styles.css
├── js/
│ └── app.js
└── images/
└── logo.png
Configuration
Configure the template and static directories in your server.yaml:
server :
templateDir : "views/" # Directory containing templates
staticDir : "views/static/" # Directory for static assets
The templateDir must contain a file named verifier_present_qr.html which will be rendered when users access the login page.
Required Template File
verifier_present_qr.html
This template is rendered at /api/v1/loginQR and must include the QR code image.
Minimum Required Template :
<! DOCTYPE html >
< html >
< head >
< title > Login with Wallet </ title >
</ head >
< body >
< h1 > Scan QR Code to Login </ h1 >
<!-- Required: QR code image -->
< img src = "data:{{.qrcode}}" alt = "Login QR Code" />
</ body >
</ html >
Data URI containing the QR code image. This must be included in the template using the exact syntax shown above.
Template Variables
The following variables are available in the template context:
Base64-encoded data URI of the QR code image. Use as: <img src="data:{{.qrcode}}" />
VCVerifier uses the goview framework for template rendering, which supports Go’s standard html/template syntax.
Static Assets
Static files in the staticDir are served at the /static path.
Example Directory Structure
views/static/
├── css/
│ └── login.css
├── js/
│ └── qr-refresh.js
└── images/
├── logo.png
└── background.svg
Accessing Static Files
Reference static files in your templates using the /static prefix:
<! DOCTYPE html >
< html >
< head >
< link rel = "stylesheet" href = "/static/css/login.css" >
< script src = "/static/js/qr-refresh.js" ></ script >
</ head >
< body >
< img src = "/static/images/logo.png" alt = "Logo" class = "logo" />
< img src = "data:{{.qrcode}}" alt = "QR Code" />
</ body >
</ html >
Complete Example
Here’s a complete example with styling and branding:
verifier_present_qr.html
static/css/login.css
static/js/login.js
<! DOCTYPE html >
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > Secure Login </ title >
< link rel = "stylesheet" href = "/static/css/login.css" >
</ head >
< body >
< div class = "container" >
< header >
< img src = "/static/images/logo.png" alt = "Company Logo" class = "logo" />
< h1 > Secure Wallet Login </ h1 >
</ header >
< main >
< div class = "qr-container" >
< img src = "data:{{.qrcode}}" alt = "Login QR Code" class = "qr-code" />
</ div >
< div class = "instructions" >
< h2 > How to Login </ h2 >
< ol >
< li > Open your wallet app </ li >
< li > Scan the QR code above </ li >
< li > Approve the authentication request </ li >
</ ol >
</ div >
</ main >
< footer >
< p > Powered by VCVerifier </ p >
</ footer >
</ div >
< script src = "/static/js/login.js" ></ script >
</ body >
</ html >
Advanced Templating
VCVerifier uses Go’s html/template engine, which supports:
{{if .someVariable}}
< p > Variable is present </ p >
{{else}}
< p > Variable is missing </ p >
{{end}}
Standard Go template functions are available:
{{printf}} - Formatted printing
{{html}} - HTML escaping
{{js}} - JavaScript escaping
{{urlquery}} - URL query escaping
< p > {{printf "Welcome to %s" "VCVerifier"}} </ p >
You can include other templates (if they exist in templateDir): {{template "header.html" .}}
< img src = "data:{{.qrcode}}" />
{{template "footer.html" .}}
Mobile Responsive Design
Ensure your template works well on mobile devices:
< head >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< style >
@media ( max-width : 768 px ) {
.container {
padding : 20 px ;
}
.qr-code {
max-width : 250 px ;
}
}
</ style >
</ head >
Testing Your Templates
Create Template Directory
mkdir -p views/static/css
mkdir -p views/static/js
mkdir -p views/static/images
Add Template File
Create views/verifier_present_qr.html with your custom HTML
Add Static Assets
Place CSS, JavaScript, and images in the static/ subdirectories
Update Configuration
server :
templateDir : "views/"
staticDir : "views/static/"
Restart VCVerifier
Restart the service to load the new templates
Test Login Page
Navigate to /api/v1/loginQR?state=test&client_callback=http://example.com
Common Use Cases
< header >
< img src = "/static/images/company-logo.png" alt = "Company" />
< h1 > {{.companyName}} Secure Login </ h1 >
</ header >
@media (prefers-color-scheme: dark) {
body {
background : #1a1a1a ;
color : #fff ;
}
.container {
background : #2d2d2d ;
}
}
Create different template files and switch based on user preference: server :
templateDir : "views/en/" # or views/es/, views/de/, etc.
< div class = "qr-container" >
< div class = "loading" id = "loading" >
< div class = "spinner" ></ div >
< p > Generating QR Code... </ p >
</ div >
< img src = "data:{{.qrcode}}"
alt = "QR Code"
onload = " document . getElementById ('loading'). style . display = 'none'" />
</ div >
Troubleshooting
Common Issues :
Template not found : Ensure verifier_present_qr.html exists in the templateDir
Static files 404 : Verify staticDir path is correct and files are in the right location
QR code not displaying : Check that you’re using <img src="data:{{.qrcode}}" /> exactly as shown
Template syntax errors : Validate your Go template syntax
Security Considerations
Always escape user input in templates
Use HTTPS in production to protect QR code content
Don’t include sensitive information in static files
Implement Content Security Policy headers
Next Steps
API Reference Learn about the loginQR endpoint parameters
Frontend Integration Integrate the login page into your application