Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/[locale]/assets/_components/assets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ import finance from "@/public/images/finance_transparent.png"
import future from "@/public/images/future_transparent.png"
import hackathon from "@/public/images/hackathon_transparent.png"
import communityHero from "@/public/images/heroes/community-hero.png"
import developersHero from "@/public/images/heroes/developers-hub-hero.jpg"
import developersHero from "@/public/images/heroes/developers-hub-hero.png"
import garden from "@/public/images/heroes/garden.jpg"
import guidesHero from "@/public/images/heroes/guides-hub-hero.jpg"
import layer2Hero from "@/public/images/heroes/layer-2-hub-hero.jpg"
import layer2Hero from "@/public/images/heroes/layer-2-hub-hero.png"
import learnHero from "@/public/images/heroes/learn-hub-hero.png"
import quizzesHub from "@/public/images/heroes/quizzes-hub-hero.png"
import roadmapHero from "@/public/images/heroes/roadmap-hub-hero.jpg"
Expand Down
2 changes: 1 addition & 1 deletion app/[locale]/developers/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import scaffoldDebugScreenshot from "@/public/images/developers/scaffold-debug-s
import stackExchangeScreenshot from "@/public/images/developers/stack-exchange-screenshot.png"
import tutorialTagsBanner from "@/public/images/developers/tutorial-tags-banner.png"
import dogeImage from "@/public/images/doge-computer.png"
import heroImage from "@/public/images/heroes/developers-hub-hero.jpg"
import heroImage from "@/public/images/heroes/developers-hub-hero.png"

const H3 = (props: ChildOnlyProp) => <h3 className="mb-8 mt-10" {...props} />

Expand Down
2 changes: 1 addition & 1 deletion app/[locale]/layer-2/_components/layer-2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import InlineLink from "@/components/ui/Link"
import { Rollups } from "@/data/networks/networks"

import useTranslation from "@/hooks/useTranslation"
import HeroImage from "@/public/images/heroes/layer-2-hub-hero.jpg"
import HeroImage from "@/public/images/heroes/layer-2-hub-hero.png"
import EthereumLogo from "@/public/images/layer-2/ethereum.png"
import WalkingImage from "@/public/images/layer-2/layer-2-walking.png"
import ExploreImage from "@/public/images/layer-2/learn-hero.png"
Expand Down
16 changes: 6 additions & 10 deletions app/[locale]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { ChevronNext } from "@/components/Chevron"
import HomeHero from "@/components/Hero/HomeHero"
import BentoCard from "@/components/Homepage/BentoCard"
import CodeExamples from "@/components/Homepage/CodeExamples"
import HomepageSectionImage from "@/components/Homepage/HomepageSectionImage"
import { getBentoBoxItems } from "@/components/Homepage/utils"
import ValuesMarqueeFallback from "@/components/Homepage/ValuesMarquee/Fallback"
import BlockHeap from "@/components/icons/block-heap.svg"
Expand Down Expand Up @@ -89,11 +90,6 @@ import { fetchRSS } from "@/lib/api/fetchRSS"
import { fetchTotalEthStaked } from "@/lib/api/fetchTotalEthStaked"
import { fetchTotalValueLocked } from "@/lib/api/fetchTotalValueLocked"
import EventFallback from "@/public/images/events/event-placeholder.png"
import BuildersImage from "@/public/images/heroes/developers-hub-hero.jpg"
import ActivityImage from "@/public/images/heroes/layer-2-hub-hero.jpg"
import LearnImage from "@/public/images/heroes/learn-hub-hero.png"
import CommunityImage from "@/public/images/heroes/quizzes-hub-hero.png"
import Hero from "@/public/images/home/hero.png"

const BentoCardSwiper = dynamic(
() => import("@/components/Homepage/BentoCardSwiper"),
Expand Down Expand Up @@ -427,7 +423,7 @@ const Page = async ({ params }: { params: Promise<{ locale: Lang }> }) => {

return (
<MainArticle className="flex w-full flex-col items-center" dir={dir}>
<HomeHero heroImg={Hero} className="w-full" locale={locale} />
<HomeHero />
<div className="w-full space-y-32 px-4 md:mx-6 lg:space-y-48">
<div className="my-20 grid w-full grid-cols-2 gap-x-4 gap-y-8 md:grid-cols-4 md:gap-x-10">
{subHeroCTAs.map(
Expand Down Expand Up @@ -507,7 +503,7 @@ const Page = async ({ params }: { params: Promise<{ locale: Lang }> }) => {
{/* Activity - The strongest ecosystem */}
<Section id="activity" variant="responsiveFlex">
<SectionBanner>
<Image src={ActivityImage} alt="" />
<HomepageSectionImage sectionId="activity" alt="" />
</SectionBanner>

<SectionContent>
Expand Down Expand Up @@ -556,7 +552,7 @@ const Page = async ({ params }: { params: Promise<{ locale: Lang }> }) => {
className="md:flex-row-reverse"
>
<SectionBanner>
<Image src={LearnImage} alt="" />
<HomepageSectionImage sectionId="learn" alt="" />
</SectionBanner>

<SectionContent>
Expand Down Expand Up @@ -637,7 +633,7 @@ const Page = async ({ params }: { params: Promise<{ locale: Lang }> }) => {
{/* Builders - Blockchain's biggest builder community */}
<Section id="builders" variant="responsiveFlex">
<SectionBanner className="relative">
<Image src={BuildersImage} alt="" />
<HomepageSectionImage sectionId="builders" alt="" />
</SectionBanner>

<SectionContent>
Expand Down Expand Up @@ -690,7 +686,7 @@ const Page = async ({ params }: { params: Promise<{ locale: Lang }> }) => {
className="md:flex-row-reverse"
>
<SectionBanner>
<Image src={CommunityImage} alt="" />
<HomepageSectionImage sectionId="community" alt="" />
</SectionBanner>

<SectionContent>
Expand Down
4 changes: 2 additions & 2 deletions app/[locale]/start/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { getMetadata } from "@/lib/utils/metadata"
import { getRequiredNamespacesForPage } from "@/lib/utils/translations"
import { getNewToCryptoWallets } from "@/lib/utils/wallets"

import HeroImage from "@/public/images/heroes/developers-hub-hero.jpg"
import HeroImage from "@/public/images/heroes/developers-hub-hero.png"
import ManDogeImage from "@/public/images/start-with-ethereum/man-doge-playing.png"

const Page = async ({ params }: { params: Promise<{ locale: Lang }> }) => {
Expand Down Expand Up @@ -92,7 +92,7 @@ export async function generateMetadata({
slug: ["start"],
title: t("page-start-meta-title"),
description: t("page-start-meta-description"),
image: "/images/heroes/developers-hub-hero.jpg",
image: "/images/heroes/developers-hub-hero.png",
})
}

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/images/heroes/developers-hub-hero.jpg
Binary file not shown.
Binary file added public/images/heroes/developers-hub-hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed public/images/heroes/layer-2-hub-hero.jpg
Binary file not shown.
Binary file added public/images/heroes/layer-2-hub-hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/images/heroes/learn-hub-hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/images/heroes/quizzes-hub-hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/home/hero-2xl.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified public/images/home/hero.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
24 changes: 24 additions & 0 deletions src/components/Hero/HomeHero/HomeHero.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Meta, StoryObj } from "@storybook/react"

import { langViewportModes } from "@/storybook/modes"

import HomeHeroComponent from "."

const meta = {
title: "Organisms / Layouts / Hero",
component: HomeHeroComponent,
parameters: {
layout: "none",
chromatic: {
modes: {
...langViewportModes,
},
},
},
} satisfies Meta<typeof HomeHeroComponent>

export default meta

export const HomeHero: StoryObj<typeof meta> = {
render: () => <HomeHeroComponent />,
}
65 changes: 47 additions & 18 deletions src/components/Hero/HomeHero/index.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,58 @@
import { getTranslations } from "next-intl/server"
import { getImageProps } from "next/image"
import { getLocale, getTranslations } from "next-intl/server"

import type { ClassNameProp, CommonHeroProps, Lang } from "@/lib/types"
import type { ClassNameProp } from "@/lib/types"

import LanguageMorpher from "@/components/Homepage/LanguageMorpher"
import { Image } from "@/components/Image"

export type HomeHeroProps = Pick<CommonHeroProps, "heroImg"> &
ClassNameProp & {
locale: Lang
}
import { cn } from "@/lib/utils/cn"
import { breakpointAsNumber } from "@/lib/utils/screen"

import heroBase from "@/public/images/home/hero.png"
import hero2xl from "@/public/images/home/hero-2xl.png"

const HomeHero = async ({ heroImg, className, locale }: HomeHeroProps) => {
const HomeHero = async ({ className }: ClassNameProp) => {
const locale = getLocale()
const t = await getTranslations({ locale, namespace: "page-index" })

const alt = t("page-index-hero-image-alt")

const common = {
alt,
sizes: `(max-width: ${breakpointAsNumber["2xl"]}px) 100vw, ${breakpointAsNumber["2xl"]}px`,
priority: true,
}

const {
props: { srcSet: srcSet2xl },
} = getImageProps({ ...common, ...hero2xl, quality: 20 })

const {
props: { srcSet: srcSetMd },
} = getImageProps({ ...common, ...heroBase, quality: 10 })

const {
props: { srcSet: srcSetBase, ...rest },
} = getImageProps({ ...common, ...heroBase, quality: 5 })

return (
<div className={className}>
<div className="h-[240px] md:h-[380px] lg:h-[480px]">
<Image
src={heroImg}
alt={t("page-index-hero-image-alt")}
// TODO: adjust value when the old theme breakpoints are removed (src/theme.ts)
sizes="(max-width: 1504px) 100vw, 1504px"
className="h-full w-full object-cover"
priority
/>
<div className={cn("w-full", className)}>
<div className="h-[240px] overflow-hidden md:h-[380px] lg:h-[480px]">
<picture>
<source
media={`(min-width: ${breakpointAsNumber["2xl"]}px)`}
srcSet={srcSet2xl}
/>
<source
media={`(min-width: ${breakpointAsNumber["md"]}px) and (max-width: ${breakpointAsNumber["2xl"] - 1}px)`}
srcSet={srcSetMd}
/>
<source
media={`(max-width: ${breakpointAsNumber["md"] - 1}px)`}
srcSet={srcSetBase}
/>
<img {...rest} alt={alt} className="h-full w-full object-cover" />
</picture>
</div>
<div className="flex flex-col items-center border-t-[3px] border-primary-low-contrast px-4 py-10 text-center">
<LanguageMorpher />
Expand Down
2 changes: 1 addition & 1 deletion src/components/Hero/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { default as ContentHero, type ContentHeroProps } from "./ContentHero"
export { default as HomeHero, type HomeHeroProps } from "./HomeHero"
export { default as HomeHero } from "./HomeHero"
export { default as HubHero } from "./HubHero"
export { default as MdxHero, type MdxHeroProps } from "./MdxHero"
export {
Expand Down
97 changes: 97 additions & 0 deletions src/components/Homepage/HomepageSectionImage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import type { StaticImageData } from "next/image"
import { getImageProps } from "next/image"

import { breakpointAsNumber } from "@/lib/utils/screen"

// Import all landscape images (all PNG now)
import developersHubHero from "@/public/images/heroes/developers-hub-hero.png"
// Import all portrait images (all PNG)
import developersHubHeroPortrait from "@/public/images/heroes/developers-hub-hero-portrait.png"
import layerTwoHubHero from "@/public/images/heroes/layer-2-hub-hero.png"
import layerTwoHubHeroPortrait from "@/public/images/heroes/layer-2-hub-hero-portrait.png"
import learnHubHero from "@/public/images/heroes/learn-hub-hero.png"
import learnHubHeroPortrait from "@/public/images/heroes/learn-hub-hero-portrait.png"
import quizzesHubHero from "@/public/images/heroes/quizzes-hub-hero.png"
import quizzesHubHeroPortrait from "@/public/images/heroes/quizzes-hub-hero-portrait.png"

const imageMap: Record<
string,
{
mobile: StaticImageData
desktop: StaticImageData
}
> = {
activity: {
mobile: layerTwoHubHero,
desktop: layerTwoHubHeroPortrait,
},
learn: {
mobile: learnHubHero,
desktop: learnHubHeroPortrait,
},
builders: {
mobile: developersHubHero,
desktop: developersHubHeroPortrait,
},
community: {
mobile: quizzesHubHero,
desktop: quizzesHubHeroPortrait,
},
}

type HomepageSectionImageProps = {
sectionId: string // e.g. "activity", "learn", "builders", "community"
alt: string
className?: string
}

export default function HomepageSectionImage({
sectionId,
alt,
className,
}: HomepageSectionImageProps) {
const images = imageMap[sectionId]

if (!images) {
throw new Error(
`Image not found for section: ${sectionId}. Available sections: ${Object.keys(imageMap).join(", ")}`
)
}

const common = {
alt,
// Be very specific: Desktop max 512px, Mobile 100vw
sizes: `(max-width: ${breakpointAsNumber.md}px) 100vw, 512px`,
priority: false,
}

const {
props: { srcSet: desktop },
} = getImageProps({
...common,
...images.desktop,
quality: 25,
})

const {
props: { srcSet: mobile, ...rest },
} = getImageProps({
...common,
...images.mobile,
quality: 40,
})

return (
<picture className={className}>
<source
media={`(min-width: ${breakpointAsNumber.md}px)`}
srcSet={desktop}
/>
<source
media={`(max-width: ${breakpointAsNumber.md - 1}px)`}
srcSet={mobile}
/>
<img {...rest} alt={alt} className="h-full w-full object-cover" />
</picture>
)
}
4 changes: 2 additions & 2 deletions src/data/roadmap/releases.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { StaticImageData } from "next/image"

import DevelopersHubHeroImage from "@/public/images/heroes/developers-hub-hero.jpg"
import DevelopersHubHeroImage from "@/public/images/heroes/developers-hub-hero.png"
import GuidesHubHeroImage from "@/public/images/heroes/guides-hub-hero.jpg"
import Layer2HubHeroImage from "@/public/images/heroes/layer-2-hub-hero.jpg"
import Layer2HubHeroImage from "@/public/images/heroes/layer-2-hub-hero.png"
import QuizzesHubHeroImage from "@/public/images/heroes/quizzes-hub-hero.png"
import FusakaImage from "@/public/images/roadmap/roadmap-fusaka.png"
import PectraImage from "@/public/images/roadmap/roadmap-pectra.png"
Expand Down
2 changes: 1 addition & 1 deletion src/lib/utils/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { routing } from "@/i18n/routing"
* List of default og images for different sections
*/
const imageForSlug = [
{ section: "developers", image: "/images/heroes/developers-hub-hero.jpg" },
{ section: "developers", image: "/images/heroes/developers-hub-hero.png" },
{ section: "roadmap", image: "/images/heroes/roadmap-hub-hero.jpg" },
{ section: "guides", image: "/images/heroes/guides-hub-hero.jpg" },
{ section: "community", image: "/images/heroes/community-hero.png" },
Expand Down