first commit
Some checks failed
Test examples / Test Examples (20) (push) Has been cancelled
Test examples / Test Examples (22) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Trigger Release / start (push) Has been cancelled
Stale issue handler / stale (push) Has been cancelled
Update Font Data / create-pull-request (push) Has been cancelled
build-and-deploy / deploy-target (push) Has been cancelled
build-and-deploy / build (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / build-wasm (nodejs) (push) Has been cancelled
build-and-deploy / build-wasm (web) (push) Has been cancelled
build-and-deploy / Deploy preview tarball (push) Has been cancelled
build-and-deploy / Potentially publish release (push) Has been cancelled
build-and-deploy / publish-turbopack-npm-packages (push) Has been cancelled
build-and-deploy / Deploy examples (push) Has been cancelled
build-and-deploy / thank you, build (push) Has been cancelled
build-and-deploy / Upload Turbopack Bytesize metrics to Datadog (push) Has been cancelled
Rspack Next.js development integration tests / Rspack integration tests (push) Has been cancelled
Rspack Next.js production integration tests / Rspack integration tests (push) Has been cancelled
Turbopack Next.js development integration tests / Next.js integration tests (push) Has been cancelled
Turbopack Next.js production integration tests / Next.js integration tests (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack development test manifest (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack production test manifest (push) Has been cancelled
Upload bundler test manifests to areweturboyet.com / Upload test results (push) Has been cancelled
Update React / create-pull-request (push) Has been cancelled
test-e2e-project-reset-cron / reset-test-project (push) Has been cancelled
Notify about the top 15 issues/PRs/feature requests (most reacted) in the last 90 days / run (push) Has been cancelled

This commit is contained in:
Arian Tron
2026-03-10 19:37:31 +03:30
commit 61f56f997c
27684 changed files with 2784175 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
import Container from "./container";
import cn from "classnames";
import { EXAMPLE_PATH } from "@/lib/constants";
type AlertProps = {
preview: boolean;
};
const Alert = (props: AlertProps) => {
const { preview } = props;
return (
<div
className={cn("border-b", {
"bg-accent-7 border-accent-7 text-white": preview,
"bg-accent-1 border-accent-2": !preview,
})}
>
<Container>
<div className="py-2 text-center text-sm">
{preview ? (
<>
This page is a preview.{" "}
<a
href="/api/exit-preview"
className="underline hover:text-cyan duration-200 transition-colors"
>
Click here
</a>{" "}
to exit preview mode.
</>
) : (
<>
The source code for this blog is{" "}
<a
href={`https://github.com/vercel/next.js/tree/canary/examples/${EXAMPLE_PATH}`}
className="underline hover:text-success duration-200 transition-colors"
>
available on GitHub
</a>
.
</>
)}
</div>
</Container>
</div>
);
};
export default Alert;

View File

@@ -0,0 +1,28 @@
import Image from "next/image";
type AvatarProps = {
name: string;
picture: string;
};
const Avatar = (props: AvatarProps) => {
const { name, picture } = props;
return (
<div className="flex items-center">
<div className="w-12 h-12 relative mr-4">
{picture && (
<Image
src={`${picture}?auto=format,compress,enhance&w=100&h=100`}
layout="fill"
className="rounded-full"
alt={name}
/>
)}
</div>
<div className="text-xl font-bold">{name}</div>
</div>
);
};
export default Avatar;

View File

@@ -0,0 +1,12 @@
import { ReactNode } from "react";
type ContainerProps = {
children: ReactNode;
};
const Container = (props: ContainerProps) => {
const { children } = props;
return <div className="container mx-auto px-5">{children}</div>;
};
export default Container;

View File

@@ -0,0 +1,43 @@
import cn from "classnames";
import Link from "next/link";
import Imgix from "react-imgix";
type CoverImageProps = {
title;
url;
slug;
};
const CoverImage = (props: CoverImageProps) => {
const { title, url, slug } = props;
const image = (
<Imgix
src={url}
alt={`Cover Image for ${title}`}
className={cn("lazyload shadow-small w-full", {
"hover:shadow-medium transition-shadow duration-200": slug,
})}
sizes="100vw"
attributeConfig={{
src: "data-src",
srcSet: "data-srcset",
sizes: "data-sizes",
}}
htmlAttributes={{
src: `${url}?auto=format,compress&q=1&blur=500&w=auto`,
}}
/>
);
return (
<div className="sm:mx-0">
{slug ? (
<Link href={`/posts/${slug}`} aria-label={title}>
{image}
</Link>
) : (
image
)}
</div>
);
};
export default CoverImage;

View File

@@ -0,0 +1,13 @@
import { parseISO, format } from "date-fns";
type DateProps = {
dateString: string;
};
const Date = (props: DateProps) => {
const { dateString } = props;
const date = parseISO(dateString);
return <time dateTime={dateString}>{format(date, "LLLL d, yyyy")}</time>;
};
export default Date;

View File

@@ -0,0 +1,32 @@
import Container from "./container";
import { EXAMPLE_PATH } from "@/lib/constants";
const Footer = () => {
return (
<footer className="bg-accent-1 border-t border-accent-2">
<Container>
<div className="py-28 flex flex-col lg:flex-row items-center">
<h3 className="text-4xl lg:text-5xl font-bold tracking-tighter leading-tight text-center lg:text-left mb-10 lg:mb-0 lg:pr-4 lg:w-1/2">
Statically Generated with Next.js.
</h3>
<div className="flex flex-col lg:flex-row justify-center items-center lg:pl-4 lg:w-1/2">
<a
href="https://nextjs.org/docs/basic-features/pages"
className="mx-3 bg-black hover:bg-white hover:text-black border border-black text-white font-bold py-3 px-12 lg:px-8 duration-200 transition-colors mb-6 lg:mb-0"
>
Read Documentation
</a>
<a
href={`https://github.com/vercel/next.js/tree/canary/examples/${EXAMPLE_PATH}`}
className="mx-3 font-bold hover:underline"
>
View on GitHub
</a>
</div>
</div>
</Container>
</footer>
);
};
export default Footer;

View File

@@ -0,0 +1,14 @@
import Link from "next/link";
const Header = () => {
return (
<h2 className="text-2xl md:text-4xl font-bold tracking-tight md:tracking-tighter leading-tight mb-20 mt-8">
<Link href="/" className="hover:underline">
Blog
</Link>
.
</h2>
);
};
export default Header;

View File

@@ -0,0 +1,47 @@
import Avatar from "./avatar";
import Date from "./date";
import CoverImage from "./cover-image";
import Link from "next/link";
import { AuthorType, ImgixType } from "interfaces";
type HeroPostProps = {
title: string;
coverImage: ImgixType;
date: string;
excerpt: string;
author: AuthorType;
slug: string;
};
const HeroPost = (props: HeroPostProps) => {
const { title, coverImage, date, excerpt, author, slug } = props;
return (
<section>
<div className="mb-8 md:mb-16">
<CoverImage title={title} url={coverImage.imgix_url} slug={slug} />
</div>
<div className="md:grid md:grid-cols-2 md:gap-x-16 lg:gap-x-8 mb-20 md:mb-28">
<div>
<h3 className="mb-4 text-4xl lg:text-6xl leading-tight">
<Link href={`/posts/${slug}`} className="hover:underline">
{title}
</Link>
</h3>
<div className="mb-4 md:mb-0 text-lg">
<Date dateString={date} />
</div>
</div>
<div>
<p className="text-lg leading-relaxed mb-4">{excerpt}</p>
<Avatar
name={author.title}
picture={author.metadata.picture.imgix_url}
/>
</div>
</div>
</section>
);
};
export default HeroPost;

View File

@@ -0,0 +1,30 @@
import { CMS_NAME, CMS_URL } from "@/lib/constants";
const Intro = () => {
return (
<section className="flex-col md:flex-row flex items-center md:justify-between mt-16 mb-16 md:mb-12">
<h1 className="text-6xl md:text-8xl font-bold tracking-tighter leading-tight md:pr-8">
Blog.
</h1>
<h4 className="text-center md:text-left text-lg mt-5 md:pl-8">
A statically generated blog example using{" "}
<a
href="https://nextjs.org/"
className="underline hover:text-success duration-200 transition-colors"
>
Next.js
</a>{" "}
and{" "}
<a
href={CMS_URL}
className="underline hover:text-success duration-200 transition-colors"
>
{CMS_NAME}
</a>
.
</h4>
</section>
);
};
export default Intro;

View File

@@ -0,0 +1,26 @@
import Alert from "./alert";
import Footer from "./footer";
import Meta from "./meta";
import "lazysizes";
import "lazysizes/plugins/parent-fit/ls.parent-fit";
import { ReactNode } from "react";
type LayoutProps = {
preview: boolean;
children: ReactNode;
};
const Layout = ({ preview, children }: LayoutProps) => {
return (
<>
<Meta />
<div className="min-h-screen">
<Alert preview={preview} />
<main>{children}</main>
</div>
<Footer />
</>
);
};
export default Layout;

View File

@@ -0,0 +1,18 @@
.markdown {
@apply text-lg leading-relaxed;
}
.markdown p,
.markdown ul,
.markdown ol,
.markdown blockquote {
@apply my-6;
}
.markdown h2 {
@apply text-3xl mt-12 mb-4 leading-snug;
}
.markdown h3 {
@apply text-2xl mt-8 mb-4 leading-snug;
}

View File

@@ -0,0 +1,44 @@
import Head from "next/head";
import { CMS_NAME, HOME_OG_IMAGE_URL } from "@/lib/constants";
const Meta = () => {
return (
<Head>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/favicon/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon/favicon-16x16.png"
/>
<link rel="manifest" href="/favicon/site.webmanifest" />
<link
rel="mask-icon"
href="/favicon/safari-pinned-tab.svg"
color="#000000"
/>
<link rel="shortcut icon" href="/favicon/favicon.ico" />
<meta name="msapplication-TileColor" content="#000000" />
<meta name="msapplication-config" content="/favicon/browserconfig.xml" />
<meta name="theme-color" content="#000" />
<link rel="alternate" type="application/rss+xml" href="/feed.xml" />
<meta
name="description"
content={`A statically generated blog example using Next.js and ${CMS_NAME}.`}
/>
<meta property="og:image" content={HOME_OG_IMAGE_URL} />
</Head>
);
};
export default Meta;

View File

@@ -0,0 +1,32 @@
import { PostType } from "interfaces";
import PostPreview from "./post-preview";
type MoreStoriesProps = {
posts: PostType[];
};
const MoreStories = (props: MoreStoriesProps) => {
const { posts } = props;
return (
<section>
<h2 className="mb-8 text-6xl md:text-7xl font-bold tracking-tighter leading-tight">
More Stories
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 md:gap-x-16 lg:gap-x-32 gap-y-20 md:gap-y-32 mb-32">
{posts.map((post) => (
<PostPreview
key={post.slug}
title={post.title}
coverImage={post.metadata.cover_image}
date={post.created_at}
author={post.metadata.author}
slug={post.slug}
excerpt={post.metadata.excerpt}
/>
))}
</div>
</section>
);
};
export default MoreStories;

View File

@@ -0,0 +1,19 @@
import markdownStyles from "./markdown-styles.module.css";
type PostBodyProps = {
content: string;
};
const PostBody = (props: PostBodyProps) => {
const { content } = props;
return (
<div className="max-w-2xl mx-auto">
<div
className={markdownStyles["markdown"]}
dangerouslySetInnerHTML={{ __html: content }}
/>
</div>
);
};
export default PostBody;

View File

@@ -0,0 +1,43 @@
import Avatar from "./avatar";
import Date from "./date";
import CoverImage from "./cover-image";
import PostTitle from "./post-title";
import { AuthorType, ImgixType } from "interfaces";
type PostHeaderProps = {
title: string;
coverImage: ImgixType;
date: string;
author: AuthorType;
};
const PostHeader = (props: PostHeaderProps) => {
const { title, coverImage, date, author } = props;
return (
<>
<PostTitle>{title}</PostTitle>
<div className="hidden md:block md:mb-12">
<Avatar
name={author.title}
picture={author.metadata.picture.imgix_url}
/>
</div>
<div className="mb-8 md:mb-16 sm:mx-0">
<CoverImage title={title} url={coverImage.imgix_url} slug={""} />
</div>
<div className="max-w-2xl mx-auto">
<div className="block md:hidden mb-6">
<Avatar
name={author.title}
picture={author.metadata.picture.imgix_url}
/>
</div>
<div className="mb-6 text-lg">
<Date dateString={date} />
</div>
</div>
</>
);
};
export default PostHeader;

View File

@@ -0,0 +1,38 @@
import Avatar from "./avatar";
import Date from "./date";
import CoverImage from "./cover-image";
import Link from "next/link";
import { AuthorType, ImgixType } from "interfaces";
type PostPreviewProps = {
title: string;
coverImage: ImgixType;
date: string;
excerpt: string;
author: AuthorType;
slug: string;
};
const PostPreview = (props: PostPreviewProps) => {
const { title, coverImage, date, excerpt, author, slug } = props;
return (
<div>
<div className="mb-5">
<CoverImage slug={slug} title={title} url={coverImage.imgix_url} />
</div>
<h3 className="text-3xl mb-3 leading-snug">
<Link href={`/posts/${slug}`} className="hover:underline">
{title}
</Link>
</h3>
<div className="text-lg mb-4">
<Date dateString={date} />
</div>
<p className="text-lg leading-relaxed mb-4">{excerpt}</p>
<Avatar name={author.title} picture={author.metadata.picture.imgix_url} />
</div>
);
};
export default PostPreview;

View File

@@ -0,0 +1,15 @@
import { ReactNode } from "react";
type PostTitleProps = {
children: ReactNode;
};
const PostTitle = (props: PostTitleProps) => {
const { children } = props;
return (
<h1 className="text-6xl md:text-7xl lg:text-8xl font-bold tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left">
{children}
</h1>
);
};
export default PostTitle;

View File

@@ -0,0 +1,5 @@
const SectionSeparator = () => {
return <hr className="border-accent-2 mt-28 mb-24" />;
};
export default SectionSeparator;