Skip to content

Feat: improve SEO #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Feb 17, 2025
Merged
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
7 changes: 7 additions & 0 deletions frontend/src/app/brand-assets/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Metadata } from "next";

import Hero from "@/components/BrandAssets/Hero";
import KlerosBadgesSection from "@/components/BrandAssets/KlerosBadgesSection";
import KlerosColorsSection from "@/components/BrandAssets/KlerosColorsSection/index";
Expand Down Expand Up @@ -36,6 +38,11 @@ import {
StyledImagesSectionQueryType,
} from "@/queries/brand-assets/styled-images-section";
import { request } from "@/utils/graphQLClient";
import { getPageMetadata } from "@/utils/seo";

export const generateMetadata = async (): Promise<Metadata> => {
return await getPageMetadata("brandAssetsPageSeo");
};

const BrandAssets: React.FC = async () => {
const heroData = await request<HeroQueryType>(heroQuery);
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/app/community/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import type { Metadata } from "next";

import CommunitiesSection from "@/components/Community/CommunitiesSection";
import Hero from "@/components/Community/hero";
import { heroQuery, HeroQueryType } from "@/queries/community/hero";
import { request } from "@/utils/graphQLClient";
import { getPageMetadata } from "@/utils/seo";

export const generateMetadata = async (): Promise<Metadata> => {
return await getPageMetadata("communityPageSeo");
};

const Community: React.FC = async () => {
const heroData = await request<HeroQueryType>(heroQuery);
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/app/cooperative/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Metadata } from "next";

import Hero from "@/components/Cooperative/hero";
import MemberSection from "@/components/Cooperative/MemberSection";
import ReportSection from "@/components/Cooperative/ReportSection";
Expand All @@ -11,6 +13,11 @@ import {
CooperativePageReportQueryType,
} from "@/queries/cooperative/report-section";
import { request } from "@/utils/graphQLClient";
import { getPageMetadata } from "@/utils/seo";

export const generateMetadata = async (): Promise<Metadata> => {
return await getPageMetadata("cooperativePageSeo");
};

const Cooperative: React.FC = async () => {
const heroData = await request<HeroQueryType>(heroQuery);
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/app/earn/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import type { Metadata } from "next";

import Hero from "@/components/Earn/Hero";
import TabSection from "@/components/Earn/TabSection";
import { heroQuery, HeroQueryType } from "@/queries/earn/hero";
import { tabSectionQuery, TabSectionQueryType } from "@/queries/earn/tabs-data";
import { request } from "@/utils/graphQLClient";
import { getPageMetadata } from "@/utils/seo";

export const generateMetadata = async (): Promise<Metadata> => {
return await getPageMetadata("earnPageSeo");
};

const Earn: React.FC = async () => {
const heroData = await request<HeroQueryType>(heroQuery);
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/app/for-builders/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Metadata } from "next";

import Hero from "@/components/ForBuilders/Hero";
import UseCasesSection from "@/components/ForBuilders/UseCasesSection";
import IntegrateSection from "@/components/IntegrateSection";
Expand All @@ -7,6 +9,11 @@ import {
UseCasesQueryType,
} from "@/queries/for-builders/use-cases";
import { request } from "@/utils/graphQLClient";
import { getPageMetadata } from "@/utils/seo";

export const generateMetadata = async (): Promise<Metadata> => {
return await getPageMetadata("forBuildersPageSeo");
};

const ForBuilders: React.FC = async () => {
const heroData = await request<HeroQueryType>(heroQuery);
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/app/for-lawyers/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import type { Metadata } from "next";

import { getPageMetadata } from "@/utils/seo";

import Hero from "./components/Hero";
import KlerosDisputeResolutionSection from "./components/KlerosDisputeResolutionSection";
import KlerosEnterpriseSection from "./components/KlerosEnterpriseSection";
import KlerosFellowSection from "./components/KlerosFellowSection";
import KlerosMediationSection from "./components/KlerosMediationSection";
import KlerosParticipateSection from "./components/KlerosParticipateSection";

export const generateMetadata = async (): Promise<Metadata> => {
return getPageMetadata("forLawyersPageSeo");
};

const ForLawyers: React.FC = async () => {
return (
<>
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/app/home/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import type { Metadata } from "next";

import IntegrateSection from "@/components/IntegrateSection";
import { getPageMetadata } from "@/utils/seo";

import CaseStudies from "./components/CaseStudies";
import GetInTouch from "./components/GetInTouch";
Expand All @@ -9,6 +12,10 @@ import StartEarning from "./components/StartEarning";
import TrustedBy from "./components/TrustedBy";
import UseCases from "./components/UseCases";

export const generateMetadata = async (): Promise<Metadata> => {
return await getPageMetadata("homePageSeo");
};

const Home: React.FC = async () => {
return (
<>
Expand Down
45 changes: 45 additions & 0 deletions frontend/src/app/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion frontend/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { Urbanist } from "next/font/google";

import Footer from "@/components/Footer";
import Navbar from "@/components/Navbar";
import { HeroImagesQueryType, herosImagesQuery } from "@/queries/heroImages";
import { navbarQuery, NavbarQueryType } from "@/queries/navbar";
import "@/styles/globals.css";
import { getHeroImgsProps } from "@/utils/getHeroImgsProps";
import { request } from "@/utils/graphQLClient";
import { HeroImagesQueryType, herosImagesQuery } from "@/queries/heroImages";

const urbanist = Urbanist({
weight: ["400", "500"],
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/app/pnk-token/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Metadata } from "next";

import BuySection from "@/components/PNKToken/BuySection";
import Hero from "@/components/PNKToken/Hero";
import TokenNeedSection from "@/components/PNKToken/TokenNeedSection";
Expand All @@ -16,6 +18,11 @@ import {
tokenomicsSectionQuery,
} from "@/queries/pnk-token/tokenomics";
import { request } from "@/utils/graphQLClient";
import { getPageMetadata } from "@/utils/seo";

export const generateMetadata = async (): Promise<Metadata> => {
return await getPageMetadata("pnkTokenPageSeo");
};

const PNKToken: React.FC = async () => {
const heroData = await request<HeroQueryType>(heroQuery);
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/app/r-and-d/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { Metadata } from "next";

import Hero from "@/components/ResearchDevelopment/Hero";
import TabSection from "@/components/ResearchDevelopment/TabSection";
import { heroQuery, HeroQueryType } from "@/queries/research-development/hero";
Expand All @@ -6,6 +8,11 @@ import {
TabSectionQueryType,
} from "@/queries/research-development/tabs-data";
import { request } from "@/utils/graphQLClient";
import { getPageMetadata } from "@/utils/seo";

export const generateMetadata = async (): Promise<Metadata> => {
return getPageMetadata("rAndDPageSeo");
};

const ResearchDevelopment: React.FC = async () => {
const heroData = await request<HeroQueryType>(heroQuery);
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/app/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
User-agent: *
Disallow:
65 changes: 65 additions & 0 deletions frontend/src/queries/seo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { gql } from "graphql-request";

const SEO_CONTENT = `
SEO {
title
description
image {
url
}
}
`;

export const seoQuery = gql`
{
brandAssetsPageSeo {
${SEO_CONTENT}
}
communityPageSeo {
${SEO_CONTENT}
}
cooperativePageSeo {
${SEO_CONTENT}
}
earnPageSeo {
${SEO_CONTENT}
}
forBuildersPageSeo {
${SEO_CONTENT}
}
forLawyersPageSeo {
${SEO_CONTENT}
}
homePageSeo {
${SEO_CONTENT}
}
pnkTokenPageSeo {
${SEO_CONTENT}
}
rAndDPageSeo {
${SEO_CONTENT}
}
}
`;

type ISEO = {
SEO: {
title: string;
description: string;
image: {
url: string;
};
};
};

export type SEOQueryType = {
brandAssetsPageSeo: ISEO;
communityPageSeo: ISEO;
cooperativePageSeo: ISEO;
earnPageSeo: ISEO;
forBuildersPageSeo: ISEO;
forLawyersPageSeo: ISEO;
homePageSeo: ISEO;
pnkTokenPageSeo: ISEO;
rAndDPageSeo: ISEO;
};
21 changes: 21 additions & 0 deletions frontend/src/utils/seo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { Metadata } from "next";

import { seoQuery, SEOQueryType } from "@/queries/seo";
import { request } from "@/utils/graphQLClient";

type PageKey = keyof SEOQueryType;

export const getPageMetadata = async (pageKey: PageKey): Promise<Metadata> => {
const seoData = await request<SEOQueryType>(seoQuery);
const { title, description, image } = seoData[pageKey].SEO;

return {
title,
description,
openGraph: {
title,
description,
images: image.url,
},
};
};