Troubleshooting
Common issues and solutions when using the VanityCert widget.
Widget Not Rendering
Container Element Not Found
Symptom: Widget doesn't appear on the page.
Cause: Target element doesn't exist when VanityCert.init() is called.
Solution:
// ❌ Wrong - script runs before DOM is ready
<script>
VanityCert.init({ target: '#ssl-widget', ... });
</script>
// ✅ Correct - wait for DOM ready
<script>
document.addEventListener('DOMContentLoaded', function() {
VanityCert.init({ target: '#ssl-widget', ... });
});
</script>
CSS Not Loaded
Symptom: Widget appears unstyled or broken.
Cause: CSS file not loaded or loaded after JavaScript.
Solution:
<!-- ✅ Load CSS before JS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@vanitycert/widget@1/vanitycert.min.css">
<script src="https://cdn.jsdelivr.net/npm/@vanitycert/widget@1/vanitycert.min.js"></script>
<!-- Check in browser DevTools: Network tab should show CSS loaded successfully -->
JavaScript Errors
Symptom: Console shows errors.
Solution: Check for common errors:
// ❌ Missing required options
VanityCert.init({
target: '#ssl-widget'
// Missing: apiEndpoint, serverId, userId
});
// ✅ All required options provided
VanityCert.init({
target: '#ssl-widget',
apiEndpoint: '/api/vanitycert-proxy',
serverId: 123,
userId: 'user-123'
});
API / Backend Errors
401 Unauthorized
Symptom: "Unauthorized" or "Invalid API key" error.
Cause: Backend proxy not configured correctly.
Solution:
- Check environment variables:
# Verify these are set
echo $VANITYCERT_API_KEY_ID
echo $VANITYCERT_API_KEY
- Verify headers in backend:
// ✅ Correct headers
headers: {
'X-API-KEY-ID': VANITYCERT_API_KEY_ID,
'X-API-KEY': VANITYCERT_API_KEY
}
// ❌ Wrong - old Bearer format
headers: {
'Authorization': `Bearer ${API_KEY}`
}
- Test backend proxy manually:
curl -X POST http://localhost:3000/api/vanitycert-proxy/domains \
-H "Content-Type: application/json" \
-d '{"url":"test.domain.com","server_id":123}'
CORS Errors
Symptom: Browser console shows CORS error.
Cause: Widget on different domain than backend proxy.
Solution:
// Backend: Enable CORS
const cors = require('cors');
app.use('/api/vanitycert-proxy', cors({
origin: 'https://yourdomain.com',
credentials: true
}));
Network Error / Timeout
Symptom: "Failed to connect to VanityCert API"
Causes & Solutions:
-
Backend not running:
# Check if server is running
curl http://localhost:3000/health -
Wrong endpoint URL:
// ❌ Wrong
apiEndpoint: '/api/proxy' // Backend expects /api/vanitycert-proxy
// ✅ Correct
apiEndpoint: '/api/vanitycert-proxy' -
Firewall blocking requests:
- Check firewall allows outbound HTTPS to app.vanitycert.com
- Check backend can reach app.vanitycert.com:
curl -I https://app.vanitycert.com/api/domains
DNS Validation Issues
DNS Validation Stuck
Symptom: Widget stuck on "Validating DNS" step for >30 minutes.
Diagnosis:
# Check DNS configuration
dig app.yourdomain.com CNAME
# Expected output:
# app.yourdomain.com. 300 IN CNAME my.vanitycert.com.
Solutions:
-
CNAME not configured:
- Add CNAME record:
app → my.vanitycert.com - Wait 5-15 minutes for propagation
- Add CNAME record:
-
Wrong CNAME target:
# ❌ Wrong targets
app.yourdomain.com. IN CNAME www.vanitycert.com.
app.yourdomain.com. IN CNAME vanitycert.com.
# ✅ Correct
app.yourdomain.com. IN CNAME my.vanitycert.com. -
Conflicting A/AAAA records:
- Remove A or AAAA records for the same subdomain
- DNS can't have both CNAME and A/AAAA records
-
Cloudflare proxy enabled:
- Disable Cloudflare proxy (grey cloud, not orange)
- Use "DNS only" mode
24-Hour Timeout
Symptom: "DNS validation timeout (24 hours)" error shown.
Solution:
- Click "Retry" button in widget
- This will delete the old domain and start fresh
- Ensure DNS is configured correctly before retrying
State / Persistence Issues
State Not Persisting
Symptom: Widget resets on page reload instead of showing progress.
Cause: LocalStorage blocked or userId changing.
Solutions:
-
Check LocalStorage enabled:
// Test in browser console
localStorage.setItem('test', '1');
console.log(localStorage.getItem('test')); // Should output '1' -
Consistent userId:
// ❌ Wrong - generates new ID each time
userId: 'user-' + Math.random()
// ✅ Correct - same ID for same user
userId: 'user-' + currentUser.id -
Browser privacy mode:
- LocalStorage may be disabled in private/incognito mode
- Users need to use normal browsing mode
Multiple Users See Same Domain
Symptom: Different users see each other's domains.
Cause: userId is the same for all users.
Solution:
// ❌ Wrong - hardcoded userId
VanityCert.init({
userId: 'user-123' // Same for everyone!
});
// ✅ Correct - unique per user
VanityCert.init({
userId: 'user-' + currentUser.id // Different for each user
});
Styling Issues
Widget Not Responsive
Symptom: Widget doesn't fit on mobile screens.
Solution:
<!-- Add viewport meta tag -->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Theme Not Applied
Symptom: Custom colors not showing.
Solutions:
-
CSS specificity issues:
/* ❌ May not override */
:root {
--vc-primary-color: #ff0000;
}
/* ✅ More specific */
.vanitycert-widget {
--vc-primary-color: #ff0000;
} -
Load order:
<!-- Load widget CSS first -->
<link rel="stylesheet" href="vanitycert.min.css">
<!-- Then your custom CSS -->
<link rel="stylesheet" href="custom.css"> -
Check theme object:
// Verify theme is passed correctly
VanityCert.init({
theme: {
primaryColor: '#ff0000' // Should be camelCase
}
});
Text Overflow
Symptom: Long domain names overflow container.
Solution:
.vc-dns-value,
.vc-domain-display {
word-break: break-all;
overflow-wrap: break-word;
}
Callback Issues
Callbacks Not Firing
Symptom: Event callbacks not being called.
Solutions:
-
Check callback names:
callbacks: {
onCertificateIssued: function(domain) { ... }, // ✅ Correct
certificateIssued: function(domain) { ... } // ❌ Wrong
} -
Check function syntax:
// ✅ All valid
onError: function(error) { console.log(error); }
onError: (error) => { console.log(error); }
onError(error) { console.log(error); } -
Verify events are occurring:
- Check browser console for widget status updates
- Use browser DevTools to monitor API responses
Multiple Callbacks Firing
Symptom: Same callback fires multiple times.
Cause: Multiple widget instances initialized.
Solution:
// ❌ Wrong - creates multiple instances
VanityCert.init({ target: '#ssl-widget', ... });
VanityCert.init({ target: '#ssl-widget', ... }); // Duplicate!
// ✅ Correct - destroy before re-initializing
VanityCert.destroy('#ssl-widget');
VanityCert.init({ target: '#ssl-widget', ... });
Performance Issues
Slow Loading
Symptom: Widget takes long to initialize.
Solutions:
-
Use minified files:
<!-- ✅ Faster -->
<script src="vanitycert.min.js"></script>
<!-- ❌ Slower -->
<script src="vanitycert.js"></script> -
Load from CDN:
<!-- CDN with caching -->
<script src="https://cdn.jsdelivr.net/npm/@vanitycert/widget@1/vanitycert.min.js"></script> -
Defer non-critical loading:
<script src="vanitycert.min.js" defer></script>
High Polling Frequency
Symptom: Too many API requests.
Solution:
// Default: polls every 5 seconds
// Reduce frequency if needed:
VanityCert.init({
pollInterval: 10000, // Check every 10s instead of 5s
dnsPollInterval: 30000 // Check DNS every 30s instead of 10s
});
Debugging Tips
Enable Console Logging
Check browser console for widget output:
// Widget logs status updates to console
// Open DevTools → Console to see:
// - Domain creation
// - Status updates
// - Errors
Inspect Network Requests
- Open DevTools → Network tab
- Filter by "vanitycert-proxy"
- Check request/response for each API call
Inspect LocalStorage
- Open DevTools → Application tab
- Expand "Local Storage"
- Look for keys like
vanitycert_user-123 - View/edit stored state
Test in Isolation
Create minimal test page:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@vanitycert/widget@1/vanitycert.min.css">
</head>
<body>
<div id="ssl-widget"></div>
<script src="https://cdn.jsdelivr.net/npm/@vanitycert/widget@1/vanitycert.min.js"></script>
<script>
VanityCert.init({
target: '#ssl-widget',
apiEndpoint: '/api/vanitycert-proxy',
serverId: 123,
userId: 'test-user',
callbacks: {
onError: (e) => alert('Error: ' + e.message)
}
});
</script>
</body>
</html>
Getting Help
Still having issues?
-
Check documentation:
-
Search GitHub issues:
-
Contact support:
- Email: support@vanitycert.com
- Include:
- Browser and version
- Console errors
- Network request/response
- Minimal reproduction code
-
Join community:
- Discord: https://discord.gg/vanitycert
- Stack Overflow: Tag with
vanitycert