blog / src /shared /config.ts
hadadrjt's picture
blog: Bump to 0.0.6 version.
6c25065
//
// SPDX-FileCopyrightText: Hadad <hadad@linuxmail.org>
// SPDX-License-Identifier: Apache-2.0
//
import type { SupportedLanguage } from "./types.js";
const LANGUAGE_DISPLAY_NAMES: Record<SupportedLanguage, string> = {
id: "Bahasa Indonesia",
zh: "Chinese",
ja: "Japanese",
fr: "French",
es: "Spanish",
};
const SITE_NAME = "Hadad Darajat";
export const siteConfig = {
name: SITE_NAME,
title: SITE_NAME,
description: "Personal Blog",
siteUrl: process.env.SITE_URL,
locale: "en-US",
author: {
name: SITE_NAME,
linkedin: "https://linkedin.com/in/hadadrjt",
},
keywords: [
"hadad",
"hadad darajat",
"hadadrjt",
"hadadxyz",
"hadad blog",
"hadad darajat blog",
"hadad personal blog",
"hadad darajat personal blog",
"blog",
"personal blog",
"technology",
"programming",
"software development",
"tech articles",
"huggingface",
"hugging face",
"hf",
"hugging face space",
],
footer: {
copyrightYear: "2025",
copyrightText: "Copyright",
},
messages: {
loading: "Please wait a moment...",
noPosts: "There are no post available at this time",
postNotFound: "Article not found",
backToHome: "Back to Home",
readMore: "Read more",
latestArticles: "Latest",
shareArticle: "Share this article",
previous: "Previous",
next: "Next",
analyzeWithAI: "Analyze this article",
analyzing: "Analyzing...",
analysisInfo: "AI Analysis",
analysisComplete: "Analysis Complete",
reasoning: "Reasoning",
closeAnalysis: "Close",
analysisError: "Failed to analyze article",
translateArticle: "Translate this article",
translating: "Translating...",
translationComplete: "Translation Complete",
translationInfo: "AI Translation",
selectLanguage: "Select Language",
translationError: "Failed to translate article",
closeTranslation: "Close",
translationReady: "Translation",
},
defaults: {
postTitle: "Untitled",
postAuthor: "Anonymous",
postDescription: "",
},
dateFormat: {
year: "numeric" as const,
month: "long" as const,
day: "numeric" as const,
},
features: {
enableAIAnalysis: true,
enableTranslation: true,
},
languages: {
id: { name: LANGUAGE_DISPLAY_NAMES["id"], flag: "🇮🇩" },
zh: { name: LANGUAGE_DISPLAY_NAMES["zh"], flag: "🇨🇳" },
ja: { name: LANGUAGE_DISPLAY_NAMES["ja"], flag: "🇯🇵" },
fr: { name: LANGUAGE_DISPLAY_NAMES["fr"], flag: "🇫🇷" },
es: { name: LANGUAGE_DISPLAY_NAMES["es"], flag: "🇪🇸" },
},
server: {
host: "0.0.0.0",
port: 3000,
jsonLimit: "2mb",
corsOptions: {
origin: true,
methods: [
"GET",
"POST"
],
allowedHeaders: ["Content-Type"],
},
},
files: {
markdownExtensionPattern: /\.(md|markdown)$/,
postsDirectoryName: "post",
indexHtmlFileName: "index.html",
clientDirectoryName: "client",
},
fileWatcher: {
persistent: true,
ignoreInitial: true,
stabilityThreshold: 300,
pollInterval: 100,
},
ai: {
model: "nvidia/nemotron-3-nano-30b-a3b",
maxTokens: 131072,
streamEnabled: true,
apiEndpoint: "/v1/chat/completions",
systemPrompts: {
analysis: `You are an AI content analysis engine embedded in a blog platform.
Your role is to analyze articles objectively for readers.
Do NOT address or speak to the author.
Do NOT use second-person language such as "you", "your", or any motivational or coaching tone.
Do NOT claim to represent the reader's perspective. Remember that you are only an AI assistant whose role is to help readers understand the content of the article.
Position yourself as a reader who happens to come across an article from the blog, and provide an explanation stating whether the article is accurate or whether it needs to be rechecked.
Your task is to analyze the article as a reader, not as someone providing improvements, and not as an instructor.`,
translation: (targetLanguage: SupportedLanguage): string => {
const targetLanguageName = LANGUAGE_DISPLAY_NAMES[targetLanguage];
return `You are a professional translator specializing in translating English blog posts into "${targetLanguageName}".
Your task is to translate the following article accurately while maintaining:
1. The original meaning and tone
2. Markdown formatting
3. Technical terms appropriately translated or kept in English if commonly used
4. Natural flow and readability in "${targetLanguageName}"
Do NOT add explanations about the translation process.
Do NOT modify the structure of the content.
Translate only the text content, preserve all markdown syntax.
Output the translated content directly.
Exclude the following metadata when translating :
---
title: .....
date: .....
description: .....
author: .....
tags: .....
---
`;
},
},
userPrompts: {
analysis: (title: string, content: string): string =>
`Please analyze this blog post titled "${title}":\n\n article:\n\n\n${content}`,
translation: (title: string, languageName: string, content: string): string =>
`Please translate this blog post titled "${title}" into "${languageName}":\n\n article:\n\n\n${content}`,
},
},
seo: {
googleVerification: "m0OGuzVr40bOdghFXVbs3AYpfEcXnrRZ83RR1DCDvoc",
bingVerification: "867CFEF9C4B44CFD5EEA1A6C65ED3F6B",
defaultRobots: "index, follow",
articleRobots: "index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1",
twitterCardType: "summary_large_image",
maxKeywords: 10,
sitemapChangeFrequency: {
home: "daily",
post: "weekly",
},
sitemapPriority: {
home: "1.0",
post: "0.8",
},
metaTagPlaceholder: "<!--SEO_META_TAGS-->",
},
logs: {
postsLoaded: (count: number): string => `Loaded ${count} posts`,
postRemoved: (slug: string): string => `Removed post: ${slug}`,
watchingDirectory: (path: string): string => `Watching for post changes in: ${path}`,
serverRunning: (host: string, port: number): string => `Server running at http://${host}:${port}`,
siteUrl: (url: string): string => `Site URL: ${url}`,
environment: (env: string): string => `Environment: ${env}`,
renderingPost: (slug: string): string => `Rendering post page for slug: ${slug}`,
foundIndexHtml: (path: string): string => `Found index.html at: ${path}`,
newPostDetected: "New post detected",
postUpdated: "Post updated",
postDeleted: "Post deleted",
},
errors: {
aiServiceNotConfigured: "AI service is not configured",
aiResponseFailed: "Failed to get AI response",
noResponseAvailable: "No response available",
connectionError: "Connection error occurred",
articleRequired: "Article is required",
targetLanguageRequired: "Target language is required",
methodNotAllowed: "Method not allowed",
articleNotFound: "Article not found",
unknownError: "Unknown error",
internalServerError: "Internal Server Error",
templateNotLoaded: "Template not loaded",
emptyHtmlReturned: "Empty HTML returned from render post page",
serverErrorCouldNotRender: "Server Error: Could not render page",
errorGeneratingSitemap: "Error generating sitemap",
couldNotFindIndexHtml: "Could not find index.html in any expected location",
searchedPaths: "Searched paths:",
couldNotFindMetaTagInsertionPoint: "Could not find insertion point for meta tags",
loadingPosts: (error: unknown): string =>
`Error loading posts: ${error instanceof Error ? error.message : String(error)}`,
loadingPost: (filename: string, error: unknown): string =>
`Error loading post ${filename}: ${error instanceof Error ? error.message : String(error)}`,
renderingPostPage: (error: unknown): string =>
`Error in renderPostPage: ${error instanceof Error ? error.message : String(error)}`,
renderingHomePage: (error: unknown): string =>
`Error rendering home page: ${error instanceof Error ? error.message : String(error)}`,
fallbackRenderFailed: (error: unknown): string =>
`Fallback render also failed: ${error instanceof Error ? error.message : String(error)}`,
aiApiError: (errorText: string): string => `AI API Error: ${errorText}`,
aiStreamError: (error: unknown): string =>
`AI Stream Error: ${error instanceof Error ? error.message : String(error)}`,
serverError: (message: string): string => `Server Error: ${message}`,
readingIndexHtml: (path: string, error: unknown): string =>
`Failed to read index.html from ${path}: ${error instanceof Error ? error.message : String(error)}`,
postNotFoundForSlug: (slug: string): string => `Post not found for slug: ${slug}`,
},
streamEvents: {
done: "done",
error: "error",
reasoning: "reasoning",
content: "content",
},
contentTypes: {
eventStream: "text/event-stream",
html: "text/html",
plain: "text/plain",
xml: "application/xml",
json: "application/json",
},
httpHeaders: {
accelBuffering: "X-Accel-Buffering",
contentType: "Content-Type",
authorization: "Authorization",
},
};
export const getLanguageDisplayName = (language: SupportedLanguage): string => {
return LANGUAGE_DISPLAY_NAMES[language];
};