teqo-backup/next.config.mjs
Francisco Solla cac8af0d6f feat(site): mapeia os permalinks do WordPress legado para o domínio novo (OPS131)
Os 43 posts publicados no WordPress (último em 2026-08-17) ganham redirect permanente do permalink /<ano>/<mês>/<dia>/<slug>/ para o caminho canônico do Teqo, com destino derivado do type/category atuais de produção. Categoria, tag, author, feeds, paginação e arquivos de data vão para /artigos; /home vai para /; wp-admin/wp-login.php para /. O mapa fica em scripts/lib/legacyWordPressRedirects.mjs (43 entradas) e é consumido pelo next.config.mjs; unit pina contagem/forma/unicidade e o e2e do frontend cobre os redirects. Sem migration, sem Consent e sem mudança de conteúdo no CMS.
2026-11-08 20:09:51 -03:00

78 lines
4.2 KiB
JavaScript

import { withPayload } from '@payloadcms/next/withPayload'
import { legacyWordPressPostRedirects } from './scripts/lib/legacyWordPressRedirects.mjs'
/** @type {import('next').NextConfig} */
const allowedImageHost = process.env.NEXT_PUBLIC_SITE_URL || 'https://jorgesolla.com.br'
const nextConfig = {
distDir: process.env.NEXT_DIST_DIR || '.next',
...(process.env.NEXT_OUTPUT_STANDALONE === '1' ? { output: 'standalone' } : {}),
// S47 — the campaign surfaces left the air after the election. The pages are
// gone from the tree; the permanent redirects keep the links that already
// circulated (and any index entry) pointing at the mandate instead of a 404.
async redirects() {
return [
// OPS131 — the old WordPress site (jorgesolla.com.br) becomes this app.
// The 43 post permalinks are enumerated (date → canonical Teqo path);
// the archive/category/tag/author routes below catch the remaining
// indexed URLs from the WordPress sitemap, plus the date archives.
...legacyWordPressPostRedirects.map((entry) => ({ ...entry, permanent: true })),
{ source: '/category/:path*', destination: '/artigos', permanent: true },
{ source: '/tag/:path*', destination: '/artigos', permanent: true },
{ source: '/author/:path*', destination: '/artigos', permanent: true },
{ source: '/feed', destination: '/artigos', permanent: true },
{ source: '/comments/feed', destination: '/artigos', permanent: true },
{ source: '/page/:path*', destination: '/artigos', permanent: true },
{ source: '/home', destination: '/', permanent: true },
{
source: '/:year(\\d{4})/:month(\\d{2})/:day(\\d{2})/:slug',
destination: '/artigos',
permanent: true,
},
{
source: '/:year(\\d{4})/:month(\\d{2})/:day(\\d{2})',
destination: '/artigos',
permanent: true,
},
{ source: '/:year(\\d{4})/:month(\\d{2})', destination: '/artigos', permanent: true },
{ source: '/:year(\\d{4})', destination: '/artigos', permanent: true },
{ source: '/wp-admin/:path*', destination: '/', permanent: true },
{ source: '/wp-login.php', destination: '/', permanent: true },
// S47 — the campaign surfaces left the air after the election. The pages are
// gone from the tree; the permanent redirects keep the links that already
// circulated (and any index entry) pointing at the mandate instead of a 404.
{ source: '/conteudos', destination: '/artigos', permanent: true },
{ source: '/conteudos/:path*', destination: '/artigos', permanent: true },
{ source: '/jingles', destination: '/', permanent: true },
{ source: '/jingles/:path*', destination: '/', permanent: true },
{ source: '/cards', destination: '/', permanent: true },
{ source: '/cards/:path*', destination: '/', permanent: true },
]
},
images: {
minimumCacheTTL: 14400,
remotePatterns: [
new URL(`${allowedImageHost}/**`),
// YouTube video thumbnails (campaign home content board, S2) come from
// the platform's CDN — see `src/utilities/socialFeed/youtubeFeed.ts`.
new URL('https://i.ytimg.com/**'),
// Instagram media thumbnails (campaign home content board, S3) come from
// the Graph API's CDN (hosts vary per region) —
// see `src/utilities/socialFeed/instagramFeed.ts`. Plain objects (not
// `new URL`) on purpose: the URL form pins `search: ''`, and Graph API
// media URLs carry a signed query string — the optimizer would reject
// them with 400 even on an allowed host.
{ protocol: 'https', hostname: '*.cdninstagram.com', pathname: '/**' },
// Meta moved Instagram Graph API media to `*.fbcdn.net`
// (`instagram.<pop>.fna.fbcdn.net`, `scontent.<pop>.fna.fbcdn.net`) —
// without this the optimizer answers 400 and every IG cover breaks.
{ protocol: 'https', hostname: '**.fbcdn.net', pathname: '/**' },
// e2e-only: the YouTube/Instagram stubs (tests/e2e/*-stub.mjs) serve the
// fixture thumbnails locally so specs never touch the real network.
{ protocol: 'http', hostname: 'localhost', pathname: '/thumbs/**' },
],
},
}
export default withPayload(nextConfig, { devBundleServerPackages: false })