Learn how to deploy your plugin to production and make it available to users.
- Deployment Overview
- GitHub Pages
- Netlify
- Vercel
- AWS S3 + CloudFront
- Custom Server
- CDN Configuration
- Best Practices
- Troubleshooting
To deploy a plugin, you need to:
- Build the plugin (
./build.sh) - Upload
index.js(and optionallyindex.js.map) to a hosting service - Configure CORS headers on the hosting service
- Register the plugin URL in digital.auto admin panel
Your hosting must:
- ✅ Serve files over HTTPS (required for production)
- ✅ Allow CORS (Cross-Origin Resource Sharing)
- ✅ Serve
Content-Type: application/javascriptheader - ✅ Have high availability and low latency
Best for: Personal projects, open-source plugins, prototypes
# Initialize git in your plugin directory
cd vehicle-dashboard
git init
# Create .gitignore
echo "node_modules" > .gitignore
echo ".DS_Store" >> .gitignore
# Initial commit
git add .
git commit -m "Initial commit"
# Create GitHub repository and push
gh repo create my-plugin --public --source=. --remote=origin --push
# Or manually create repo on GitHub and pushOption A: Via GitHub Website
- Go to repository settings
- Navigate to "Pages" section
- Select source: "Deploy from a branch"
- Select branch:
mainormaster - Select folder:
/(root) - Click "Save"
Option B: Via GitHub Actions
Create .github/workflows/deploy.yml:
name: Deploy Plugin
on:
push:
branches: [ main ]
permissions:
contents: read
pages: write
id-token: write
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: yarn install
- name: Build plugin
run: ./build.sh
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: '.'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2Your plugin will be available at:
https://username.github.io/repository-name/index.js
Example:
https://johndoe.github.io/vehicle-dashboard/index.js
In the admin panel:
- Name: Vehicle Dashboard
- Slug:
vehicle-dashboard - URL:
https://johndoe.github.io/vehicle-dashboard/index.js
Best for: Modern web apps, automatic deployments, edge functions
npm install -g netlify-cli./build.shOption A: Manual Deploy
# Deploy current directory
netlify deploy --prod
# Follow prompts:
# - Create new site? Yes
# - Publish directory: . (current directory)
# Your plugin will be deployed to:
# https://random-name-123.netlify.app/index.jsOption B: Connect GitHub Repository
- Create
netlify.tomlin your repository:
[build]
command = "./build.sh"
publish = "."
[[headers]]
for = "/*"
[headers.values]
Access-Control-Allow-Origin = "*"
Content-Type = "application/javascript; charset=utf-8"-
Push to GitHub
-
Go to Netlify
- Click "Add new site" → "Import an existing project"
- Connect to GitHub
- Select your repository
- Click "Deploy site"
-
Your plugin will be at:
https://your-site-name.netlify.app/index.js
- In Netlify dashboard, go to "Domain settings"
- Click "Add custom domain"
- Add your domain (e.g.,
plugins.example.com) - Follow DNS configuration instructions
- Enable HTTPS (automatic with Let's Encrypt)
Your plugin will be at:
https://plugins.example.com/index.js
Best for: Next.js apps, serverless functions, edge computing
npm install -g vercel# From your plugin directory
vercel
# Follow prompts:
# - Set up and deploy? Yes
# - Which scope? Your account
# - Link to existing project? No
# - Project name? vehicle-dashboard
# - In which directory is your code? ./
# - Want to override settings? No
# Your plugin will be at:
# https://vehicle-dashboard.vercel.app/index.jsCreate vercel.json:
{
"buildCommand": "./build.sh",
"outputDirectory": ".",
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "Access-Control-Allow-Origin",
"value": "*"
},
{
"key": "Content-Type",
"value": "application/javascript; charset=utf-8"
}
]
}
]
}vercel --prod# Add domain
vercel domains add plugins.example.com
# Follow DNS configuration instructionsBest for: Enterprise deployments, high traffic, custom CDN configuration
# Install AWS CLI
brew install awscli # macOS
# or: https://aws.amazon.com/cli/
# Configure AWS credentials
aws configure
# Create bucket
aws s3 mb s3://my-plugin-bucket
# Enable static website hosting
aws s3 website s3://my-plugin-bucket \
--index-document index.jsCreate bucket-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-plugin-bucket/*"
}
]
}Apply policy:
aws s3api put-bucket-policy \
--bucket my-plugin-bucket \
--policy file://bucket-policy.jsonCreate cors.json:
{
"CORSRules": [
{
"AllowedOrigins": ["*"],
"AllowedHeaders": ["*"],
"AllowedMethods": ["GET", "HEAD"],
"MaxAgeSeconds": 3000
}
]
}Apply CORS:
aws s3api put-bucket-cors \
--bucket my-plugin-bucket \
--cors-configuration file://cors.json# Build plugin
./build.sh
# Upload to S3
aws s3 cp index.js s3://my-plugin-bucket/ \
--content-type "application/javascript" \
--cache-control "public, max-age=31536000"
# Optional: Upload source map
aws s3 cp index.js.map s3://my-plugin-bucket/ \
--content-type "application/json"# Create distribution
aws cloudfront create-distribution \
--origin-domain-name my-plugin-bucket.s3.amazonaws.com \
--default-root-object index.js
# Note the Distribution ID and Domain Name
# Domain: d1234567890abc.cloudfront.netYour plugin will be at:
https://d1234567890abc.cloudfront.net/index.js
- Create SSL certificate in AWS Certificate Manager
- Configure CloudFront to use custom domain
- Update DNS CNAME record
Plugin will be at:
https://plugins.example.com/index.js
Create deploy.sh:
#!/bin/bash
set -e
echo "Building plugin..."
./build.sh
echo "Uploading to S3..."
aws s3 cp index.js s3://my-plugin-bucket/ \
--content-type "application/javascript" \
--cache-control "public, max-age=31536000"
echo "Invalidating CloudFront cache..."
aws cloudfront create-invalidation \
--distribution-id YOUR_DISTRIBUTION_ID \
--paths "/index.js"
echo "✅ Deployment complete!"Best for: Full control, existing infrastructure
server {
listen 443 ssl;
server_name plugins.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
root /var/www/plugins;
location ~* \.js$ {
add_header Access-Control-Allow-Origin *;
add_header Content-Type "application/javascript; charset=utf-8";
add_header Cache-Control "public, max-age=31536000";
}
location ~* \.map$ {
add_header Access-Control-Allow-Origin *;
add_header Content-Type "application/json";
}
}<VirtualHost *:443>
ServerName plugins.example.com
DocumentRoot /var/www/plugins
SSLEngine on
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/key.pem
<FilesMatch "\.js$">
Header set Access-Control-Allow-Origin "*"
Header set Content-Type "application/javascript; charset=utf-8"
Header set Cache-Control "public, max-age=31536000"
</FilesMatch>
<FilesMatch "\.map$">
Header set Access-Control-Allow-Origin "*"
Header set Content-Type "application/json"
</FilesMatch>
</VirtualHost>Create Dockerfile:
FROM nginx:alpine
# Copy nginx config
COPY nginx.conf /etc/nginx/conf.d/default.conf
# Copy plugin files
COPY index.js /usr/share/nginx/html/
COPY index.js.map /usr/share/nginx/html/
EXPOSE 80Create nginx.conf:
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
location ~* \.js$ {
add_header Access-Control-Allow-Origin *;
add_header Content-Type "application/javascript; charset=utf-8";
}
}Build and run:
docker build -t my-plugin .
docker run -p 8080:80 my-plugin
# Plugin available at:
# http://localhost:8080/index.js- Sign up at Cloudflare
- Add your domain
- Update nameservers
- Create Page Rule:
- URL:
plugins.example.com/*.js - Settings:
- Cache Level: Cache Everything
- Edge Cache TTL: 1 year
- URL:
- Configure CORS in Workers (optional):
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const response = await fetch(request)
const newResponse = new Response(response.body, response)
newResponse.headers.set('Access-Control-Allow-Origin', '*')
newResponse.headers.set('Content-Type', 'application/javascript')
return newResponse
}Approach 1: Query Parameters
https://example.com/plugin.js?v=1.2.3
Approach 2: Path-based
https://example.com/v1.2.3/plugin.js
Approach 3: Hash-based (Recommended)
https://example.com/plugin-abc123.js
Update vite.config.js:
export default defineConfig({
build: {
lib: {
fileName: () => `index-[hash].js`
}
}
})For Production Builds:
Cache-Control: public, max-age=31536000, immutable
For Development:
Cache-Control: no-cache
Upload source maps for debugging:
# Upload both files
aws s3 cp index.js s3://bucket/
aws s3 cp index.js.map s3://bucket/Or keep source maps private:
# Upload only .js file
aws s3 cp index.js s3://bucket/Create a health check endpoint:
Create health.json:
{
"status": "ok",
"plugin": "vehicle-dashboard",
"version": "1.0.0",
"updated": "2025-01-14T00:00:00Z"
}Upload:
aws s3 cp health.json s3://bucket/Check health:
curl https://example.com/health.jsonTrack plugin loads:
// Add to plugin
console.log('[Plugin] Loaded at', new Date().toISOString());
// Send analytics
if (window.gtag) {
window.gtag('event', 'plugin_load', {
plugin_name: 'vehicle-dashboard',
plugin_version: '1.0.0'
});
}Error: Access to script at 'https://...' from origin 'https://...' has been blocked by CORS
Solution: Add CORS headers:
Access-Control-Allow-Origin: *
Error: Plugin doesn't execute
Solution: Ensure Content-Type header:
Content-Type: application/javascript; charset=utf-8
Error: Old version loads after update
Solution:
- Use versioned URLs:
plugin.js?v=1.2.3 - Clear CDN cache
- Use cache busting:
plugin-[hash].js
Error: NET::ERR_CERT_AUTHORITY_INVALID
Solution:
- Use Let's Encrypt for free SSL
- Ensure certificate is valid and not expired
- Test with:
curl -v https://example.com/plugin.js
Check:
- ✅ URL is accessible:
curl https://example.com/plugin.js - ✅ Returns JavaScript code
- ✅ CORS headers present
- ✅ HTTPS (not HTTP)
- ✅ Content-Type is
application/javascript - ✅ Plugin registers on
window.DAPlugins['page-plugin']
Enable verbose logging:
// Add to plugin
console.log('[Plugin] Initializing...');
console.log('[Plugin] Data:', data);
console.log('[Plugin] API:', api);
console.log('[Plugin] Config:', config);
// In host app, check:
console.log('DAPlugins:', window.DAPlugins);Before deploying to production:
- Plugin builds without errors
- Tested locally with
npx serve - CORS configured correctly
- HTTPS enabled
- Content-Type header correct
- Cache headers configured
- Source maps uploaded (optional)
- Plugin registered in admin panel
- Tested in production environment
- Monitoring/analytics configured
- Documentation updated
- Version tagged in git
- 📚 Review all documentation
- 🛠️ Build and deploy your plugin
- 💡 Share your plugin with the community
- 🚀 Explore Advanced Topics for optimization
-
Hosting Providers:
-
SSL Certificates:
-
CDN Services: