Deployment

Deploy your Qlik TypeScript SDK applications to production environments with confidence using best practices and proven strategies.

๐ŸŒ Browser-Only Deployment

The Qlik TypeScript SDK is designed exclusively for browser environments. All deployment strategies focus on client-side applications that run in modern browsers.

โœ… Supported: Static site hosting, CDN deployment, client-side applications
โœ… Environments: Qlik Cloud, Qlik Sense Enterprise
โŒ Not supported: Node.js server-side execution, server-side rendering

Deployment Overview

Deploying Qlik applications requires careful consideration of security, performance, environment configuration, and monitoring. This guide covers deployment strategies for various hosting platforms and environments.

Cloud Platforms
AWS, Azure, GCP, Vercel, Netlify
On-Premise
Docker, Kubernetes, traditional servers
Security
HTTPS, secrets management, authentication
CI/CD
Automated testing and deployment

Production Readiness Checklist

Pre-Deployment Checklist

Essential items to verify before deploying to production

โœ… Security

HTTPS enforced for all connections
Environment variables for sensitive data
Web Integration ID properly configured
CORS origins whitelist configured
Authentication error handling implemented

๐Ÿ“Š Performance

Caching strategies implemented
Bundle optimization and code splitting
Lazy loading for large datasets
Error boundaries implemented
Performance monitoring configured

๐Ÿงช Testing

Unit tests pass with > 80% coverage
Integration tests with Qlik APIs
End-to-end testing completed
Cross-browser compatibility tested
Mobile responsiveness verified

โš™๏ธ Configuration

Environment-specific configurations
Logging and monitoring setup
Health check endpoints implemented
Backup and recovery procedures
Documentation updated

Deployment Strategies

Vercel Deployment

Deploy Next.js Qlik applications to Vercel

1. Environment Configuration

bash
# .env.local (for local development)
QLIK_HOST=your-tenant.us.qlikcloud.com
QLIK_WEB_INTEGRATION_ID=your-web-integration-id
NEXT_PUBLIC_APP_ENV=development

# .env.production (Vercel environment variables)
QLIK_HOST=prod-tenant.us.qlikcloud.com
QLIK_WEB_INTEGRATION_ID=prod-web-integration-id
NEXT_PUBLIC_APP_ENV=production

2. Vercel Configuration

json
// vercel.json
{
  "build": {
    "env": {
      "QLIK_HOST": "@qlik-host",
      "QLIK_WEB_INTEGRATION_ID": "@qlik-web-integration-id"
    }
  },
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "X-Frame-Options",
          "value": "DENY"
        },
        {
          "key": "X-Content-Type-Options",
          "value": "nosniff"
        },
        {
          "key": "Strict-Transport-Security",
          "value": "max-age=31536000; includeSubDomains"
        }
      ]
    }
  ],
  "redirects": [
    {
      "source": "/",
      "has": [
        {
          "type": "host",
          "value": "(?<host>.*)"
        }
      ],
      "destination": "https://your-domain.vercel.app",
      "permanent": false
    }
  ]
}

3. Deployment Script

bash
#!/bin/bash
# deploy.sh

echo "๐Ÿš€ Starting Vercel deployment..."

# Set environment variables in Vercel
vercel env add QLIK_HOST production
vercel env add QLIK_WEB_INTEGRATION_ID production

# Build and deploy
vercel build --prod
vercel deploy --prod

echo "โœ… Deployment completed!"

# Verify deployment
curl -f https://your-app.vercel.app/api/health || exit 1
echo "โœ… Health check passed!"

4. GitHub Actions Integration

yaml
# .github/workflows/deploy.yml
name: Deploy to Vercel

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          
      - name: Install dependencies
        run: npm ci
        
      - name: Run tests
        run: npm test
        
      - name: Build application
        run: npm run build
        
      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v20
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-args: '--prod'
          vercel-org-id: ${{ secrets.ORG_ID }}
          vercel-project-id: ${{ secrets.PROJECT_ID }}

Monitoring & Observability

Production Monitoring Setup

Implement comprehensive monitoring for your deployed application

typescript
// utils/monitoring.ts
class ProductionMonitoring {
  private metricsEndpoint: string;
  private apiKey: string;

  constructor(config: { metricsEndpoint: string; apiKey: string }) {
    this.metricsEndpoint = config.metricsEndpoint;
    this.apiKey = config.apiKey;
  }

  // Application performance monitoring
  trackPageLoad(pageName: string, loadTime: number): void {
    this.sendMetric({
      type: 'performance',
      name: 'page_load',
      value: loadTime,
      tags: { page: pageName },
      timestamp: Date.now()
    });
  }

  trackQlikOperation(operation: string, duration: number, success: boolean): void {
    this.sendMetric({
      type: 'qlik_operation',
      name: operation,
      value: duration,
      tags: { success: success.toString() },
      timestamp: Date.now()
    });
  }

  trackError(error: Error, context: string): void {
    this.sendMetric({
      type: 'error',
      name: 'application_error',
      value: 1,
      tags: {
        error_type: error.name,
        context: context,
        message: error.message.substring(0, 100)
      },
      timestamp: Date.now()
    });
  }

  trackUserAction(action: string, metadata?: Record<string, any>): void {
    this.sendMetric({
      type: 'user_action',
      name: action,
      value: 1,
      tags: metadata || {},
      timestamp: Date.now()
    });
  }

  private async sendMetric(metric: any): Promise<void> {
    try {
      await fetch(this.metricsEndpoint, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${this.apiKey}`
        },
        body: JSON.stringify(metric)
      });
    } catch (error) {
      console.error('Failed to send metric:', error);
    }
  }
}

// Health check endpoint
// pages/api/health.ts
import { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  try {
    // Check database connectivity (if applicable)
    // Check external service connectivity (Qlik)
    const qlikHealthy = await checkQlikConnectivity();
    
    const health = {
      status: 'healthy',
      timestamp: new Date().toISOString(),
      version: process.env.npm_package_version || '1.0.0',
      environment: process.env.NODE_ENV,
      uptime: process.uptime(),
      memory: process.memoryUsage(),
      services: {
        qlik: qlikHealthy ? 'healthy' : 'unhealthy'
      }
    };

    const statusCode = qlikHealthy ? 200 : 503;
    res.status(statusCode).json(health);

  } catch (error) {
    res.status(503).json({
      status: 'unhealthy',
      error: error.message,
      timestamp: new Date().toISOString()
    });
  }
}

async function checkQlikConnectivity(): Promise<boolean> {
  try {
    // Basic connectivity check to Qlik
    const response = await fetch(`https://${process.env.QLIK_HOST}/api/v1/users/me`, {
      method: 'HEAD',
      timeout: 5000
    });
    return response.ok;
  } catch {
    return false;
  }
}

๐Ÿš€ Deployment Best Practices

Security First: Always use HTTPS and secure secret management
Environment Separation: Maintain separate configurations for dev/staging/production
Automated Testing: Include comprehensive testing in your CI/CD pipeline
Monitoring: Implement logging, metrics, and alerting from day one
Scalability: Design for horizontal scaling and high availability
Rollback Strategy: Always have a plan for rolling back deployments
Performance: Optimize bundles, enable compression, and use CDNs
Documentation: Maintain up-to-date deployment and runbook documentation