mirror of
https://github.com/Xevion/xevion.dev.git
synced 2026-01-31 12:26:39 -06:00
Complete architectural overhaul migrating from Directus+tRPC to Payload CMS with Next.js App Router. This represents a fundamental shift in how the application is structured and how data is managed. Major changes: - Migrated from Pages Router (src/pages/) to App Router (src/app/) - Replaced Directus CMS with Payload CMS as the content management system - Removed tRPC in favor of Payload's built-in API routes - Added PostgreSQL database via Docker Compose for local development - Implemented separate route groups for frontend and Payload admin - Updated all API routes to App Router conventions - Added Payload collections for Projects, Technologies, Links, Media, and Users - Configured ESLint for new project structure Infrastructure: - Added docker-compose.yml for PostgreSQL database - Updated environment variables for Payload CMS configuration - Integrated @payloadcms/next for seamless Next.js integration - Added GraphQL API and playground routes Dependencies: - Upgraded React from 18.2.0 to 19.2.0 - Upgraded Next.js to 15.5.6 - Added Payload CMS 3.x packages (@payloadcms/db-postgres, @payloadcms/next, etc.) - Removed Directus SDK and tRPC packages - Updated Sharp to 0.34.x - Migrated to @tanstack/react-query v5
96 lines
2.3 KiB
JavaScript
96 lines
2.3 KiB
JavaScript
import { withPayload } from "@payloadcms/next/withPayload";
|
|
// @ts-check
|
|
|
|
import withPlaiceholder from "@plaiceholder/next";
|
|
|
|
/**
|
|
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation.
|
|
* This is especially useful for Docker builds.
|
|
*/
|
|
if (!process.env.SKIP_ENV_VALIDATION) await import("./src/env/server.mjs");
|
|
|
|
/**
|
|
*
|
|
* @param {string} text The string to search around with the pattern in.
|
|
* @param {string} pattern The strict, text only pattern to search for.
|
|
* @param {number} nth The index of the pattern to find.
|
|
* @returns
|
|
*/
|
|
function nthIndex(text, pattern, nth) {
|
|
const L = text.length;
|
|
let i = -1;
|
|
while (nth-- && i++ < L) {
|
|
i = text.indexOf(pattern, i);
|
|
if (i < 0) break;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
const v2_redirects = [
|
|
"/2020/12/04/jekyll-github-pages-and-azabani",
|
|
"/2021/02/25/project-facelift-new-and-old",
|
|
"/2022/03/29/runnerspace-built-in-under-30-hours",
|
|
"/2022/07/16/restricted-memory-and-data-framing-tricks",
|
|
"/drafts/2022-09-19-presenting-to-humans/",
|
|
"/photography",
|
|
].map((url) => {
|
|
// If the URL starts with /2, redirect to the new blog. Otherwise, redirect to the old v2 blog to maintain URLs.
|
|
if (url.startsWith("/2"))
|
|
return {
|
|
source: url,
|
|
destination: `https://undefined.behavio.rs/posts${url.slice(
|
|
nthIndex(url, "/", 4),
|
|
)}`,
|
|
permanent: false,
|
|
};
|
|
|
|
return {
|
|
source: url,
|
|
destination: `https://v2.xevion.dev${url}`,
|
|
permanent: false,
|
|
};
|
|
});
|
|
|
|
/** @type {import("next").NextConfig} */
|
|
const config = {
|
|
reactStrictMode: true,
|
|
images: {
|
|
remotePatterns: [
|
|
{
|
|
protocol: "https",
|
|
hostname: "img.walters.to",
|
|
},
|
|
{
|
|
protocol: "https",
|
|
hostname: "img.xevion.dev",
|
|
},
|
|
{
|
|
protocol: "https",
|
|
hostname: "api.xevion.dev",
|
|
},
|
|
],
|
|
},
|
|
async redirects() {
|
|
// Source cannot end with / slash
|
|
return [
|
|
...[
|
|
"resume.pdf",
|
|
"resume.docx",
|
|
"resume.txt",
|
|
"resum",
|
|
"resumee",
|
|
"cv",
|
|
"cover.pdf",
|
|
"cv.docx",
|
|
"cv.pdf",
|
|
].map((ext) => ({
|
|
source: `/${ext}`,
|
|
destination: "/resume",
|
|
permanent: true,
|
|
})),
|
|
...v2_redirects,
|
|
];
|
|
},
|
|
};
|
|
export default withPayload(withPlaiceholder(config));
|