vkashti / scripts / static-export.js
static-export.js
Raw
#!/usr/bin/env node

/**
 * This script creates a simple static export of the site
 * completely bypassing the Next.js build system to avoid any errors.
 * It creates a minimal landing page that redirects to a "site under maintenance" message.
 */

const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');

console.log('๐Ÿš€ Starting static export process...');

// Create output directories
const outputDir = path.join(process.cwd(), '.next');
if (!fs.existsSync(outputDir)) {
  fs.mkdirSync(outputDir, { recursive: true });
}

const staticDir = path.join(outputDir, 'static');
if (!fs.existsSync(staticDir)) {
  fs.mkdirSync(staticDir, { recursive: true });
}

// Create a simple HTML maintenance page
function createMaintenancePage() {
  const maintenanceContent = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Site Maintenance - VKASHTI</title>
  <style>
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
      margin: 0;
      padding: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      min-height: 100vh;
      background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
      text-align: center;
    }
    .container {
      max-width: 800px;
      padding: 2rem;
      background-color: white;
      border-radius: 8px;
      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    }
    h1 {
      color: #333;
      margin-bottom: 1rem;
    }
    p {
      color: #666;
      line-height: 1.6;
      margin-bottom: 1.5rem;
    }
    .logo {
      max-width: 200px;
      margin-bottom: 2rem;
    }
    .btn {
      display: inline-block;
      background-color: #4a90e2;
      color: white;
      padding: 0.75rem 1.5rem;
      border-radius: 4px;
      text-decoration: none;
      font-weight: 500;
      transition: background-color 0.2s;
    }
    .btn:hover {
      background-color: #357abD;
    }
  </style>
</head>
<body>
  <div class="container">
    <h1>VKASHTI - Site Maintenance</h1>
    <p>We're currently performing maintenance on our site to bring you an even better experience.</p>
    <p>Our team is working hard to complete these updates as quickly as possible.</p>
    <p>Please check back soon. We apologize for any inconvenience.</p>
    <a href="javascript:window.location.reload()" class="btn">Refresh Page</a>
  </div>
</body>
</html>`;

  // Write the maintenance page
  fs.writeFileSync(path.join(outputDir, 'maintenance.html'), maintenanceContent);
  console.log('โœ… Created maintenance page');
  
  // Also create a 404 page
  fs.writeFileSync(path.join(outputDir, '404.html'), maintenanceContent);
  console.log('โœ… Created 404 page');
}

// Create a simple index page that redirects to the maintenance page
function createIndexPage() {
  const indexContent = `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="refresh" content="0;url=/maintenance.html">
  <title>Redirecting...</title>
</head>
<body>
  <p>Redirecting to maintenance page...</p>
  <script>
    window.location.href = '/maintenance.html';
  </script>
</body>
</html>`;

  // Write the index page
  fs.writeFileSync(path.join(outputDir, 'index.html'), indexContent);
  console.log('โœ… Created redirect page');
}

// Create a build manifest to satisfy Vercel
function createBuildManifest() {
  const manifest = {
    pages: {
      "/_app": [],
      "/": ["static/index.js"],
      "/maintenance": ["static/maintenance.js"]
    },
    devFiles: [],
    ampDevFiles: [],
    lowPriorityFiles: [],
    rootMainFiles: [],
    pages404: false,
    buildId: "static-export-" + Date.now(),
    reactLoadableManifest: {},
    version: require(path.join(process.cwd(), 'node_modules/next/package.json')).version,
  };

  // Write the build manifest
  fs.writeFileSync(
    path.join(outputDir, 'build-manifest.json'),
    JSON.stringify(manifest, null, 2)
  );
  console.log('โœ… Created build manifest');
  
  // Create empty JS files referenced in the manifest
  fs.writeFileSync(path.join(staticDir, 'index.js'), '// Static export');
  fs.writeFileSync(path.join(staticDir, 'maintenance.js'), '// Static export');
}

// Create a minimal prerender-manifest.json file
function createPrerenderManifest() {
  const prerenderManifest = {
    version: 4,
    routes: {
      "/": {
        initialRevalidateSeconds: false,
        srcRoute: null,
        dataRoute: null
      },
      "/maintenance": {
        initialRevalidateSeconds: false,
        srcRoute: null,
        dataRoute: null
      }
    },
    dynamicRoutes: {},
    notFoundRoutes: [],
    preview: {
      previewModeId: "preview-mode-id-" + Date.now(),
      previewModeSigningKey: "preview-key-" + Date.now(),
      previewModeEncryptionKey: "encryption-key-" + Date.now()
    }
  };

  // Write the prerender manifest
  fs.writeFileSync(
    path.join(outputDir, 'prerender-manifest.json'),
    JSON.stringify(prerenderManifest, null, 2)
  );
  console.log('โœ… Created prerender manifest');
}

// Create required Next.js build files
function createNextBuildFiles() {
  // Create an empty routes-manifest.json
  const routesManifest = {
    version: 3,
    pages404: false,
    basePath: "",
    redirects: [],
    headers: [],
    dynamicRoutes: [],
    staticRoutes: [
      {
        page: "/",
        regex: "^/(?:/)?$",
        routeKeys: {},
        namedRegex: "^/(?:/)?$"
      },
      {
        page: "/maintenance",
        regex: "^/maintenance(?:/)?$",
        routeKeys: {},
        namedRegex: "^/maintenance(?:/)?$"
      }
    ],
    dataRoutes: []
  };

  fs.writeFileSync(
    path.join(outputDir, 'routes-manifest.json'),
    JSON.stringify(routesManifest, null, 2)
  );
  console.log('โœ… Created routes manifest');
}

// Create a simple package.json in the .next directory
function createPackageJson() {
  const pkgJson = {
    name: "static-export",
    version: "1.0.0",
    private: true,
    description: "Static export of the site",
    main: "index.js",
    dependencies: {}
  };
  
  fs.writeFileSync(
    path.join(outputDir, 'package.json'),
    JSON.stringify(pkgJson, null, 2)
  );
  console.log('โœ… Created package.json for static export');
}

// Execute static export
(async function main() {
  try {
    // Create all required files
    console.log('๐Ÿ“ฆ Creating static export files...');
    
    // Create the HTML files
    createMaintenancePage();
    createIndexPage();
    
    // Create the JSON manifests (these can fail if Next.js expects specific properties)
    try {
      createBuildManifest();
      createPrerenderManifest();
      createNextBuildFiles();
    } catch (manifestErr) {
      console.error('โš ๏ธ Warning: Error creating manifests:', manifestErr.message);
      console.log('Continuing with basic files only...');
    }
    
    // Always create a package.json
    createPackageJson();
    
    // Create a minimal server.js file as an additional fallback
    const serverJsPath = path.join(outputDir, 'server.js');
    fs.writeFileSync(serverJsPath, `
const http = require('http');
const fs = require('fs');
const path = require('path');

const server = http.createServer((req, res) => {
  // Always serve the maintenance page
  const maintenancePath = path.join(__dirname, 'maintenance.html');
  const content = fs.readFileSync(maintenancePath, 'utf8');
  res.writeHead(200, { 'Content-Type': 'text/html' });
  res.end(content);
});

const port = process.env.PORT || 3000;
server.listen(port, () => {
  console.log(\`Server running on port \${port}\`);
});
`);
    console.log('โœ… Created fallback server script');
    
    // Create a minimal module.json to satisfy Vercel
    const moduleJson = { type: "commonjs" };
    fs.writeFileSync(
      path.join(outputDir, 'module.json'),
      JSON.stringify(moduleJson, null, 2)
    );
    
    // The most basic fallback - a direct index.html in case all else fails
    fs.copyFileSync(
      path.join(outputDir, 'maintenance.html'), 
      path.join(outputDir, 'index.html')
    );
    
    console.log('โœ… Static export completed successfully!');
    process.exit(0);
  } catch (err) {
    // If anything fails, create a super minimal index.html as a last resort
    try {
      console.error('โŒ Static export failed:', err.message);
      console.log('Creating emergency fallback...');
      
      if (!fs.existsSync(outputDir)) {
        fs.mkdirSync(outputDir, { recursive: true });
      }
      
      fs.writeFileSync(
        path.join(outputDir, 'index.html'),
        `<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>VKASHTI - Site Under Maintenance</title>
</head>
<body style="font-family: sans-serif; text-align: center; padding: 50px;">
  <h1>VKASHTI - Site Under Maintenance</h1>
  <p>We're currently updating our website. Please check back soon.</p>
</body>
</html>`
      );
      console.log('โœ… Emergency fallback created');
      process.exit(0);
    } catch (emergencyErr) {
      console.error('๐Ÿ’ฅ Critical failure in emergency fallback:', emergencyErr);
      process.exit(1);
    }
  }
})();