Enable KeyStatic CMS for production

Changes:
- Added Netlify adapter for server-side rendering
- Changed output mode from static to server
- Updated KeyStatic storage from local to GitHub
- Removed SKIP_KEYSTATIC from Netlify build
- KeyStatic Admin UI will be available at /keystatic

Features:
- Server-side rendering with Netlify Functions
- GitHub integration for content management
- Production-ready KeyStatic Admin UI

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Buğra Canata
2026-01-17 20:05:42 +03:00
parent 8f64fb1eea
commit e05f99a0d2
5312 changed files with 102603 additions and 284 deletions
@@ -0,0 +1,77 @@
import slugify from 'limax';
const SITE = {"name":"Amatör Radyocular Derneği (ARC)","site":"https://www.radio.org.tr","base":"/","trailingSlash":false,"googleSiteVerificationId":"orcPxI47GSa-cRvY11tUe6iGg2IO_RPvnA1q95iEM3M"};
const I18N = {"language":"tr","textDirection":"ltr"};
const METADATA = {"title":{"default":"Amatör Radyocular Derneği (ARC)","template":"%s — ARC"},"description":"İstanbul merkezli kâr amacı gütmeyen bu dernek, amatör telsizciliği yaygınlaştırmak, eğitim vermek ve röle-beacon altyapıları işletmek amacıyla kurulmuştur.","openGraph":{"type":"website","site_name":"Amatör Radyocular Derneği (ARC)","images":[{"url":"~/assets/images/2024/12/ARC_2024_bayrak_logo-Large-1-1024x1024.png","width":1024,"height":1024,"alt":"Amatör Radyocular Derneği Logo"}]},"twitter":{"handle":"@YM1KTC","site":"@YM1KTC","cardType":"summary_large_image"}};
const APP_BLOG = {"postsPerPage":6,"post":{"permalink":"/%slug%","robots":{"index":true,"follow":true}},"list":{"pathname":"blog","robots":{"follow":true}},"category":{"pathname":"kategori","robots":{"index":true,"follow":true}},"tag":{"pathname":"etiket","robots":{"index":false,"follow":true}}};
const UI = {"theme":"system"};
const formatter = new Intl.DateTimeFormat(I18N?.language, {
year: "numeric",
month: "short",
day: "numeric",
timeZone: "UTC"
});
const getFormattedDate = (date) => date ? formatter.format(date) : "";
const trim = (str = "", ch) => {
let start = 0, end = str.length || 0;
while (start < end && str[start] === ch) ++start;
while (end > start && str[end - 1] === ch) --end;
return start > 0 || end < str.length ? str.substring(start, end) : str;
};
const trimSlash = (s) => trim(trim(s, "/"));
const createPath = (...params) => {
const paths = params.map((el) => trimSlash(el)).filter((el) => !!el).join("/");
return "/" + paths + ("");
};
const BASE_PATHNAME = SITE.base;
const cleanSlug = (text = "") => trimSlash(text).split("/").map((slug) => slugify(slug)).join("/");
const BLOG_BASE = cleanSlug(APP_BLOG?.list?.pathname);
const CATEGORY_BASE = cleanSlug(APP_BLOG?.category?.pathname);
const TAG_BASE = cleanSlug(APP_BLOG?.tag?.pathname) || "tag";
const POST_PERMALINK_PATTERN = trimSlash(APP_BLOG?.post?.permalink);
const getCanonical = (path = "") => {
const url = String(new URL(path, SITE.site));
if (path && url.endsWith("/")) {
return url.slice(0, -1);
}
return url;
};
const getPermalink = (slug = "", type = "page") => {
let permalink;
if (slug.startsWith("https://") || slug.startsWith("http://") || slug.startsWith("://") || slug.startsWith("#") || slug.startsWith("javascript:")) {
return slug;
}
switch (type) {
case "home":
permalink = getHomePermalink();
break;
case "blog":
permalink = getBlogPermalink();
break;
case "asset":
permalink = getAsset(slug);
break;
case "category":
permalink = createPath(CATEGORY_BASE, trimSlash(slug));
break;
case "tag":
permalink = createPath(TAG_BASE, trimSlash(slug));
break;
case "post":
permalink = createPath(trimSlash(slug));
break;
case "page":
default:
permalink = createPath(slug);
break;
}
return definitivePermalink(permalink);
};
const getHomePermalink = () => getPermalink("/");
const getBlogPermalink = () => getPermalink(BLOG_BASE);
const getAsset = (path) => "/" + [BASE_PATHNAME, path].map((el) => trimSlash(el)).filter((el) => !!el).join("/");
const definitivePermalink = (permalink) => createPath(BASE_PATHNAME, permalink);
export { APP_BLOG as A, BLOG_BASE as B, CATEGORY_BASE as C, I18N as I, METADATA as M, POST_PERMALINK_PATTERN as P, SITE as S, TAG_BASE as T, UI as U, getPermalink as a, getAsset as b, getCanonical as c, getBlogPermalink as d, cleanSlug as e, getFormattedDate as f, getHomePermalink as g, trimSlash as t };