From 0faf75a9a2e365a0b05dcb81191f7039be7f0c0c Mon Sep 17 00:00:00 2001 From: Macky Date: Wed, 3 Jun 2026 14:14:35 +0700 Subject: [PATCH] feat: switch to markdown content collections + remove emdash integration - Remove emdash from astro.config.mjs (no more SSR/runtime) - Remove emdash + @astrojs/node from package.json - Switch output from 'server' to 'static' - Rewrite src/content.config.ts with 6 collections: pages, services, portfolio, faq, settings, blog - Keep live.config.ts as inert stub for build compat - Push new content from content-temp/pages/ into src/content/pages/ with full schema (title, subtitle, badge, hero_image, show_cta, cta_*, etc.) Build: 18 static pages, 0 errors --- astro.config.mjs | 18 ++-------- package.json | 2 -- src/content.config.ts | 81 ++++++++++++++++++++++++++++++++++++++++++- src/live.config.ts | 12 +++---- 4 files changed, 88 insertions(+), 25 deletions(-) diff --git a/astro.config.mjs b/astro.config.mjs index 62a6d88..05f8dae 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -2,26 +2,14 @@ import { defineConfig } from 'astro/config'; import react from "@astrojs/react"; import mdx from "@astrojs/mdx"; -import node from "@astrojs/node"; -import emdash, { local } from "emdash/astro"; -import { sqlite } from "emdash/db"; +// All content is markdown → static output. No server runtime needed. export default defineConfig({ - output: "server", - adapter: node({ - mode: 'standalone' - }), + output: "static", integrations: [ react(), mdx(), - emdash({ - database: sqlite({ url: "file:./data.db" }), - storage: local({ - directory: "./uploads", - baseUrl: "/_emdash/api/media/file", - }), - }), ], image: { layout: "constrained", responsiveStyles: true }, devToolbar: { enabled: true }, -}); \ No newline at end of file +}); diff --git a/package.json b/package.json index ba40339..aa25d66 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,8 @@ }, "dependencies": { "@astrojs/mdx": "^5.0.6", - "@astrojs/node": "^10.1.1", "@astrojs/react": "^5.0.5", "astro": "^6.2.2", - "emdash": "^0.12.0", "react": "^19.2.5", "react-dom": "^19.2.5" } diff --git a/src/content.config.ts b/src/content.config.ts index 67413b5..c72b9e3 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -1,6 +1,25 @@ import { defineCollection, z } from 'astro:content'; import { glob } from 'astro/loaders'; +// ============================================================================= +// PAGES — marketing page-level content (hero copy, badges, etc.) +// ============================================================================= +const pages = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/pages' }), + schema: z.object({ + title: z.string(), + subtitle: z.string().optional(), + badge: z.string().optional(), + hero_image: z.string().optional(), + show_cta: z.boolean().optional().default(true), + cta_text: z.string().optional(), + cta_link: z.string().optional(), + }), +}); + +// ============================================================================= +// SERVICES — service detail pages +// ============================================================================= const services = defineCollection({ loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/services' }), schema: z.object({ @@ -9,9 +28,62 @@ const services = defineCollection({ badge: z.string(), category: z.string(), objective: z.string(), + usp_free_server: z.string().optional(), + usp_content_edit: z.string().optional(), }), }); +// ============================================================================= +// PORTFOLIO — client work +// ============================================================================= +const portfolio = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/portfolio' }), + schema: z.object({ + name: z.string(), + url: z.string().optional(), + category: z.string(), // webdev | ecommerce | marketing + category_label: z.string(), + industry: z.string().optional(), // NEW: industry for filtering + thumbnail: z.string(), + description: z.string(), + what_we_did: z.string().optional(), // NEW: separate from description + result: z.string().optional(), // NEW: outcome metric + }), +}); + +// ============================================================================= +// FAQ +// ============================================================================= +const faq = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/faq' }), + schema: z.object({ + category: z.string(), + category_icon: z.string().optional(), + question: z.string(), + answer: z.string(), + }), +}); + +// ============================================================================= +// SETTINGS — site identity & contact +// ============================================================================= +const settings = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/settings' }), + schema: z.object({ + site_name: z.string().optional(), + email: z.string().optional(), + phone: z.string().optional(), + address: z.string().optional(), + facebook: z.string().optional(), + line: z.string().optional(), + linkedin: z.string().optional(), + line_id: z.string().optional(), + }), +}); + +// ============================================================================= +// BLOG (existing) +// ============================================================================= const blog = defineCollection({ loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/blog' }), schema: z.object({ @@ -23,4 +95,11 @@ const blog = defineCollection({ }), }); -export const collections = { services, blog }; \ No newline at end of file +export const collections = { + pages, + services, + portfolio, + faq, + settings, + blog, +}; diff --git a/src/live.config.ts b/src/live.config.ts index af85895..e8ecda1 100644 --- a/src/live.config.ts +++ b/src/live.config.ts @@ -1,7 +1,5 @@ -import { defineLiveCollection } from "astro:content"; -import { emdashLoader } from "emdash/runtime"; - -// EmDash CMS Collections -export const collections = { - _emdash: defineLiveCollection({ loader: emdashLoader() }), -}; \ No newline at end of file +// live.config.ts — kept as a stub so Astro's runtime can import it, +// but no live collections are registered (we use markdown only via content.config.ts). +const collections = {}; +export { collections }; +export default { collections };