loading and seo optimization, big design update

This commit is contained in:
2026-04-24 01:50:41 +07:00
parent de5bf60e73
commit e8b9eb5c52
20 changed files with 866 additions and 405 deletions
+2 -2
View File
@@ -24,11 +24,11 @@ export default async function BlogIndexPage({ params }: Props) {
let records: PBPost[] = [];
try {
// Динамически выбираем таблицу: posts_ru или posts_en
records = await pb.collection(`posts_${lang}`).getFullList<PBPost>({
filter: "published = true",
sort: "-created",
cache: "no-store",
fetch: (url, config) =>
fetch(url, { ...config, next: { revalidate: 3600 } }),
});
} catch (err) {
console.error("Failed to fetch blog posts:", err);
+2
View File
@@ -9,6 +9,8 @@ import { Footer } from "@/components/sections/Footer";
const jetbrainsMono = JetBrains_Mono({
subsets: ["latin", "cyrillic"],
display: "swap",
preload: true, // Гарантирует предзагрузку в <head>
fallback: ["monospace"], // Указывает браузеру, что показывать до загрузки
});
// Настройка метаданных
+35 -6
View File
@@ -1,11 +1,39 @@
import { Suspense } from "react";
import dynamic from "next/dynamic";
import { getDictionary } from "@/lib/dictionaries";
import { Hero } from "@/components/sections/Hero";
import { Features } from "@/components/sections/Features";
import { Pricing } from "@/components/sections/Pricing";
import { FAQ } from "@/components/sections/Faq";
import { BlogPreview } from "@/components/sections/BlogPreview";
import { TerminalGuestbook } from "@/components/sections/TerminalGuestbook";
// Легкий скелетон для плавности
const SectionSkeleton = () => (
<div className="h-[500px] w-full animate-pulse bg-card/20 rounded-3xl my-10" />
);
// Ленивая загрузка тяжелых секций
const Pricing = dynamic(
() => import("@/components/sections/Pricing").then((mod) => mod.Pricing),
{
loading: () => <SectionSkeleton />,
},
);
const FAQ = dynamic(
() => import("@/components/sections/Faq").then((mod) => mod.FAQ),
{
loading: () => <SectionSkeleton />,
},
);
const TerminalGuestbook = dynamic(
() =>
import("@/components/sections/TerminalGuestbook").then(
(mod) => mod.TerminalGuestbook,
),
{
loading: () => <SectionSkeleton />,
},
);
const BlogPreview = dynamic(() =>
import("@/components/sections/BlogPreview").then((mod) => mod.BlogPreview),
);
export default async function Home({
params,
@@ -17,13 +45,14 @@ export default async function Home({
return (
<>
{/* Добавили передачу lang в Hero */}
<Hero dict={dict.hero} lang={lang} />
<Features dict={dict.features} />
{/* Теперь эти секции загрузятся только когда понадобятся */}
<Pricing dict={dict.pricing} lang={lang} />
<FAQ dict={dict.faq} lang={lang} />
<TerminalGuestbook dict={dict.guestbook} />
<Suspense fallback={<div className="py-20 text-center">Loading...</div>}>
<Suspense fallback={<SectionSkeleton />}>
<BlogPreview lang={lang} dict={dict.blog} />
</Suspense>
</>