fix(blog): resolve blog slug detail fetching and standardize api url
All checks were successful
Deploy Canina / deploy (push) Successful in 1m32s

This commit is contained in:
parsa aghaei 2026-08-24 15:20:13 +03:30
parent 5371f1ba22
commit 5bf9ac0b2e
2 changed files with 40 additions and 26 deletions

View File

@ -4,30 +4,34 @@ import Link from 'next/link';
import Image from 'next/image';
import type { Metadata } from 'next';
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'https://apicanina.parsaaghayi.ir';
async function getBlog(slug: string) {
async function getBlog(rawSlug: string) {
try {
const res = await fetch(`${API_URL}/api/blogs/${slug}`, { next: { revalidate: 60 } });
if (!res.ok) throw new Error('Failed to fetch blog');
const slug = decodeURIComponent(rawSlug);
const apiUrl = process.env.INTERNAL_API_URL || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4001/api';
const apiBase = apiUrl.endsWith('/api') ? apiUrl : `${apiUrl.replace(/\/$/, '')}/api`;
const res = await fetch(`${apiBase}/blogs/${encodeURIComponent(slug)}`, { next: { revalidate: 60 } });
if (!res.ok) {
console.error(`[Blog] Failed to fetch blog ${slug}: ${res.status}`);
return null;
}
const b = await res.json();
return {
id: b.id,
slug: b.slug,
title: b.title,
excerpt: b.metaDescription || b.content.substring(0, 150).replace(/<[^>]+>/g, '') + '...',
image: b.imageUrl,
date: new Date(b.createdAt).toLocaleDateString('fa-IR'),
author: b.author ? `${b.author.firstName} ${b.author.lastName}` : 'نویسنده کنینا',
content: b.content
excerpt: b.metaDescription || (typeof b.content === 'string' ? b.content.substring(0, 150).replace(/<[^>]+>/g, '') + '...' : ''),
image: b.imageUrl || b.coverImage || '/assets/images/blog-placeholder.png',
date: b.createdAt ? new Date(b.createdAt).toLocaleDateString('fa-IR') : '',
author: b.author ? `${b.author.firstName || ''} ${b.author.lastName || ''}`.trim() : 'نویسنده کنینا',
content: b.content || '',
};
} catch (error) {
console.error(error);
console.error('[Blog] Error fetching blog detail:', error);
return null;
}
}
export const revalidate = 60; // ensure SSR dynamic revalidation works correctly
export const revalidate = 60;
import { getSeoConfig, formatPageTitle } from "../../../lib/seo";

View File

@ -11,24 +11,34 @@ export async function generateMetadata(): Promise<Metadata> {
}
async function getBlogs() {
const rawApiUrl = process.env.NEXT_PUBLIC_API_URL || 'http://127.0.0.1:4001/api';
const apiBase = rawApiUrl.endsWith('/api') ? rawApiUrl : `${rawApiUrl}/api`;
const apiUrl = process.env.INTERNAL_API_URL || process.env.NEXT_PUBLIC_API_URL || 'http://localhost:4001/api';
const apiBase = apiUrl.endsWith('/api') ? apiUrl : `${apiUrl.replace(/\/$/, '')}/api`;
try {
const res = await fetch(`${apiBase}/blogs`, { next: { revalidate: 60 } });
if (!res.ok) throw new Error('Failed to fetch blogs');
if (!res.ok) {
console.error(`[Blog] Failed to fetch blogs: ${res.status}`);
return [];
}
const data = await res.json();
return (data.data || data).map((b: Record<string, unknown>) => ({
id: String(b.id || ''),
slug: String(b.slug || ''),
title: String(b.title || ''),
excerpt: String(b.metaDescription || (typeof b.content === 'string' ? b.content.substring(0, 150).replace(/<[^>]+>/g, '') + '...' : '')),
category: String(b.category || 'تغذیه و سلامت'),
date: String(b.createdAt || new Date().toISOString()).split('T')[0],
readTime: '۵ دقیقه',
imageUrl: String(b.coverImage || 'https://images.unsplash.com/photo-1548767797-d8c844163c4c?auto=format&fit=crop&q=80&w=800'),
}));
const list = Array.isArray(data.data) ? data.data : Array.isArray(data) ? data : [];
return list.map((b: Record<string, unknown>) => {
const authorObj = b.author as Record<string, string> | undefined;
const authorName = authorObj ? `${authorObj.firstName || ''} ${authorObj.lastName || ''}`.trim() : 'نویسنده کنینا';
return {
id: String(b.id || ''),
slug: String(b.slug || ''),
title: String(b.title || ''),
excerpt: String(b.metaDescription || (typeof b.content === 'string' ? b.content.substring(0, 150).replace(/<[^>]+>/g, '') + '...' : '')),
category: String(b.category || 'تغذیه و سلامت'),
date: b.createdAt ? new Date(String(b.createdAt)).toLocaleDateString('fa-IR') : '',
readTime: '۵ دقیقه',
image: String(b.imageUrl || b.coverImage || 'https://images.unsplash.com/photo-1548767797-d8c844163c4c?auto=format&fit=crop&q=80&w=800'),
author: authorName || 'نویسنده کنینا',
content: String(b.content || ''),
};
});
} catch (error) {
console.error(error);
console.error('[Blog] Error fetching blogs:', error);
return [];
}
}