Files
biblical-guide.com/middleware.ts
Claude Assistant d4b0062521 Implement comprehensive homepage improvements and SEO optimization
Major homepage and SEO enhancements based on optimization document:

**Homepage Content Updates:**
- Updated H1 titles with SEO-optimized text for both RO/EN
- Enhanced hero descriptions with targeted keywords
- Improved feature descriptions for better clarity
- Updated daily verse section with keyword-rich titles
- Added new footer description with SEO focus

**SEO Implementation:**
- Added dynamic metadata generation with locale-specific SEO
- Implemented Open Graph tags for social media sharing
- Added Twitter Card metadata for enhanced sharing
- Integrated Schema.org JSON-LD structured data
- Set up hreflang tags for international SEO
- Added canonical URLs to prevent duplicate content
- Included targeted keywords for both languages

**Technical Improvements:**
- Migrated from Docker to PM2 deployment
- Removed Docker files and updated deployment scripts
- Updated README with PM2 instructions
- Fixed console log cleanup for production
- Added proper favicon with Next.js app directory
- Increased memory limit to 4GB for better performance
- Updated port configuration to 0.0.0.0:3010
- Set Romanian (/ro) as default locale with proper redirects

**Translation Updates:**
- Enhanced Romanian translations with SEO-optimized content
- Updated English translations with matching SEO improvements
- Added new 'seo' namespace for metadata translations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-22 18:40:21 +00:00

83 lines
2.8 KiB
TypeScript

import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import createIntlMiddleware from 'next-intl/middleware'
import { locales } from './i18n'
// Internationalization configuration
const intlMiddleware = createIntlMiddleware({
locales: [...locales],
defaultLocale: 'ro',
localePrefix: 'always'
})
// Note: Avoid using Prisma or any Node-only APIs in Middleware.
// Middleware runs on the Edge runtime, where Prisma is not supported.
// If rate limiting is needed, implement it inside API route handlers
// (Node.js runtime) or via an external service (e.g., Upstash Redis).
export async function middleware(request: NextRequest) {
// Handle internationalization for non-API routes
if (!request.nextUrl.pathname.startsWith('/api')) {
return intlMiddleware(request)
}
// Skip API rate limiting here to stay Edge-safe
// Security headers for all responses
const response = NextResponse.next()
// Security headers
response.headers.set('X-Content-Type-Options', 'nosniff')
response.headers.set('X-Frame-Options', 'DENY')
response.headers.set('X-XSS-Protection', '1; mode=block')
response.headers.set('Referrer-Policy', 'origin-when-cross-origin')
response.headers.set('Permissions-Policy', 'camera=(), microphone=(), geolocation=()')
// CSRF protection for state-changing operations
if (['POST', 'PUT', 'DELETE', 'PATCH'].includes(request.method)) {
const origin = request.headers.get('origin')
const host = request.headers.get('host')
if (origin && host && !origin.endsWith(host)) {
return new NextResponse('Forbidden', { status: 403 })
}
}
// Authentication: perform only lightweight checks in Middleware (Edge).
// Defer full JWT verification to API route handlers (Node runtime).
const protectedPaths = ['/dashboard', '/profile', '/settings']
const isProtectedPath = protectedPaths.some(path =>
request.nextUrl.pathname.startsWith(path)
)
if (isProtectedPath) {
const token = request.cookies.get('authToken')?.value ||
request.headers.get('authorization')?.replace('Bearer ', '')
if (!token) {
// Extract locale from pathname for redirect
const locale = request.nextUrl.pathname.split('/')[1]
const isValidLocale = ['ro', 'en'].includes(locale)
const redirectLocale = isValidLocale ? locale : 'ro'
return NextResponse.redirect(new URL(`/${redirectLocale}/auth/login`, request.url))
}
}
return response
}
export const config = {
matcher: [
// Match all pathnames except for
// - api routes
// - _next (Next.js internals)
// - _vercel
// - static files (images, etc.)
// - favicon.ico, robots.txt, sitemap.xml
'/((?!api|_next|_vercel|.*\\..*|favicon.ico|robots.txt|sitemap.xml).*)',
// Match internationalized pathnames
'/(ro|en)/:path*'
],
}