113 lines
4.0 KiB
JavaScript
113 lines
4.0 KiB
JavaScript
import express from 'express';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import seoMiddleware from './seo-middleware.js';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
const app = express();
|
|
const PORT = process.env.PORT || 3000;
|
|
|
|
// Configure MIME types for JSX files
|
|
app.use((req, res, next) => {
|
|
if (req.path.endsWith('.jsx')) {
|
|
res.setHeader('Content-Type', 'application/javascript');
|
|
}
|
|
next();
|
|
});
|
|
|
|
// Serve static assets FIRST (CSS, JS, images, fonts) - these MUST work
|
|
// CRITICAL: These must be BEFORE SEO middleware to prevent JS/CSS from being intercepted
|
|
|
|
// Block /src files in production - they should never be requested
|
|
// If requested, return 404 immediately to prevent SEO middleware from intercepting
|
|
app.use('/src', (req, res) => {
|
|
res.status(404).setHeader('Content-Type', 'text/plain').send('Source files not available in production');
|
|
});
|
|
|
|
// Serve /assets (built files) - BOTH /assets and /home/assets
|
|
app.use('/assets', express.static(path.join(__dirname, '../dist/assets')));
|
|
app.use('/home/assets', express.static(path.join(__dirname, '../dist/assets')));
|
|
|
|
// Serve /og images - BOTH /og and /home/og
|
|
app.use('/og', express.static(path.join(__dirname, '../dist/og')));
|
|
app.use('/home/og', express.static(path.join(__dirname, '../dist/og')));
|
|
|
|
// Serve favicon and other root files for /home/ paths
|
|
app.use('/home/PozoAppFavicon.png', express.static(path.join(__dirname, '../dist/PozoAppFavicon.png')));
|
|
app.use('/home/fav.ico', express.static(path.join(__dirname, '../dist/fav.ico')));
|
|
app.use('/home/manifest.json', express.static(path.join(__dirname, '../dist/manifest.json')));
|
|
|
|
// Serve all other static files from dist (but NOT index.html)
|
|
app.use(express.static(path.join(__dirname, '../dist'), {
|
|
index: false, // Don't serve index.html automatically
|
|
setHeaders: (res, filePath) => {
|
|
// Set correct MIME types
|
|
if (filePath.endsWith('.css')) {
|
|
res.setHeader('Content-Type', 'text/css');
|
|
} else if (filePath.endsWith('.js')) {
|
|
res.setHeader('Content-Type', 'application/javascript');
|
|
} else if (filePath.endsWith('.html')) {
|
|
res.status(404).end();
|
|
return;
|
|
}
|
|
}
|
|
}));
|
|
|
|
// CRITICAL: Explicit handler for /src/ requests - prevent them from reaching SEO middleware
|
|
// If static middleware didn't serve it, return 404 instead of falling through
|
|
app.use('/src', (req, res, next) => {
|
|
// If we reach here, the static middleware didn't find the file
|
|
// Return 404 instead of letting it fall through to SEO middleware
|
|
res.status(404).setHeader('Content-Type', 'text/plain').send('File not found');
|
|
});
|
|
|
|
// 301 Redirects Middleware - SAFE ADDITION (no removal)
|
|
// Handles duplicate URLs, trailing slashes, and old URL redirects
|
|
app.use((req, res, next) => {
|
|
const url = req.url;
|
|
const host = req.headers.host || '';
|
|
|
|
// Force HTTPS redirect (if not already HTTPS)
|
|
if (req.protocol !== 'https' && process.env.NODE_ENV === 'production') {
|
|
return res.redirect(301, `https://${host}${url}`);
|
|
}
|
|
|
|
// Remove trailing slash (except for root and directories)
|
|
if (url.length > 1 && url.endsWith('/') && !url.includes('.')) {
|
|
return res.redirect(301, url.slice(0, -1));
|
|
}
|
|
|
|
// Normalize /home/* to /* (if needed after migration)
|
|
// Commented out for now - uncomment when ready to remove /home prefix
|
|
// if (url.startsWith('/home/') && url !== '/home/') {
|
|
// return res.redirect(301, url.replace('/home', ''));
|
|
// }
|
|
|
|
// Old URL redirects (add more as needed)
|
|
const redirectMap = {
|
|
'/pricing-pozoapp': '/pricing',
|
|
'/home/pricing-pozoapp': '/pricing',
|
|
'/home/pricing-pozoapp/': '/pricing',
|
|
};
|
|
|
|
if (redirectMap[url]) {
|
|
return res.redirect(301, redirectMap[url]);
|
|
}
|
|
|
|
next();
|
|
});
|
|
|
|
// CRITICAL: Apply SEO middleware AFTER static files and redirects
|
|
// This ensures HTML requests go through SEO middleware
|
|
// But static assets are served first
|
|
app.use(seoMiddleware);
|
|
|
|
app.listen(PORT, () => {
|
|
console.log(`Server running on port ${PORT}`);
|
|
console.log('Dynamic SEO enabled!');
|
|
});
|
|
|
|
export default app;
|