Skip to content

Commit

Permalink
feat(saas): Improved SEO, Metadata to pages
Browse files Browse the repository at this point in the history
  • Loading branch information
alifarooq9 committed May 12, 2024
1 parent 676e55e commit 787142c
Show file tree
Hide file tree
Showing 35 changed files with 306 additions and 53 deletions.
20 changes: 19 additions & 1 deletion starterkits/saas/src/app/(web)/blog/[...slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getBlogs } from "@/server/actions/blog";
import { format } from "date-fns";
import Image from "next/image";
import { notFound, redirect } from "next/navigation";
import { type Metadata } from "next";

export const dynamic = "force-static";

Expand All @@ -14,6 +15,23 @@ type BlogSlugPageProps = {
};
};

export async function generateMetadata({
params,
}: BlogSlugPageProps): Promise<Metadata> {
const slug = `/${params.slug.join("/")}`;

const blog = (await getBlogs()).find((b) => b.metaData.slug === slug);

if (!blog) {
return notFound();
}

return {
title: blog.metaData.title,
description: blog.metaData.description,
};
}

export async function generateStaticParams() {
const blogs = await getBlogs();

Expand All @@ -27,7 +45,7 @@ export default async function BlogSlugPage({ params }: BlogSlugPageProps) {
return redirect(siteUrls.blog);
}

const slug = params.slug.join("/");
const slug = `/${params.slug.join("/")}`;

const blog = (await getBlogs()).find((b) => b.metaData.slug === slug);

Expand Down
3 changes: 3 additions & 0 deletions starterkits/saas/src/app/(web)/blog/_constants/page-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const blogPageConfig = {
title: "Blog",
} as const;
6 changes: 6 additions & 0 deletions starterkits/saas/src/app/(web)/blog/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import { getBlogs } from "@/server/actions/blog";
import { format } from "date-fns";
import Image from "next/image";
import Link from "next/link";
import { type Metadata } from "next";
import { blogPageConfig } from "@/app/(web)/blog/_constants/page-config";

export const metadata: Metadata = {
title: blogPageConfig.title,
};

export const dynamic = "force-static";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const changelogPageConfig = {
title: "Change Log",
} as const;
13 changes: 8 additions & 5 deletions starterkits/saas/src/app/(web)/changelog/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ import { siteConfig } from "@/config/site";
import { getChangelogs } from "@/server/actions/changelog";
import { format } from "date-fns";
import Image from "next/image";
import type { Metadata } from "next";
import { changelogPageConfig } from "@/app/(web)/changelog/_constants/page-config";

export const metadata: Metadata = {
title: changelogPageConfig.title,
};

export const dynamic = "force-static";

Expand All @@ -35,11 +41,8 @@ export default async function ChangeLogPage() {
</p>
</WebPageHeader>
<div className="grid w-full max-w-4xl gap-8">
{changelogs.map((changelog) => (
<ChangeLogCard
key={changelog.metaData.slug}
{...changelog}
/>
{changelogs.map((changelog, index) => (
<ChangeLogCard key={index} {...changelog} />
))}
</div>
</WebPageWrapper>
Expand Down
7 changes: 6 additions & 1 deletion starterkits/saas/src/app/(web)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import { siteUrls } from "@/config/urls";
import Image from "next/image";
import Link from "next/link";
import Balancer from "react-wrap-balancer";
import type { Metadata } from "next";

export const metadata: Metadata = {
title: "Build Your MVP in Days, not weeks. Next.js Starter Kit",
};

export const dynamic = "force-static";

Expand All @@ -19,7 +24,7 @@ export default async function HomePage() {
<WebPageWrapper>
<WebPageHeader
badge="Launch your saas in 24 hours"
title="Rapidly launch your MVP with Beautiful Starterkits, Blocks, and more."
title="Build Your MVP in Days, not weeks. Open Source Starter Kit"
>
<Balancer
as="p"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const pricingPageConfig = {
title: "Pricing",
} as const;
6 changes: 6 additions & 0 deletions starterkits/saas/src/app/(web)/pricing/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import {
WebPageHeader,
WebPageWrapper,
} from "@/app/(web)/_components/general-components";
import { type Metadata } from "next";
import { pricingPageConfig } from "@/app/(web)/pricing/_constants/page-config";

/**
* Customize the pricing page to your needs. You can use the `PricingPlans` component to display the pricing plans.
Expand All @@ -11,6 +13,10 @@ import {
* To customize the pricing plans, you can modify the `PricingPlans` component. @see /app/(web)/pricing/components/pricing-plans.tsx
*/

export const metadata: Metadata = {
title: pricingPageConfig.title,
};

export default function PricingPage() {
return (
<WebPageWrapper>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { siteConfig } from "@/config/site";

export const supportPageConfig = {
title: "Support",
description: `Get support from ${siteConfig.name} to get started building your next project.`,
} as const;
12 changes: 11 additions & 1 deletion starterkits/saas/src/app/(web)/support/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,21 @@ import {
import { type SupportInfo, supportInfos } from "@/config/support";
import { ArrowRightIcon } from "lucide-react";
import Link from "next/link";
import { type Metadata } from "next";
import { supportPageConfig } from "@/app/(web)/support/_constants/page-config";

export const metadata: Metadata = {
title: supportPageConfig.title,
description: supportPageConfig.description,
};

export default function ContactPage() {
return (
<WebPageWrapper>
<WebPageHeader title="Support for You" badge="Get in touch with us">
<WebPageHeader
title={supportPageConfig.title}
badge="Get in touch with us"
>
<p>
If you have any questions or need help, feel free to reach
out to us.
Expand Down
6 changes: 6 additions & 0 deletions starterkits/saas/src/app/auth/login/_constants/page-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { siteConfig } from "@/config/site";

export const loginPageConfig = {
title: "Login",
description: `Login to ${siteConfig.name} to get started building your next project.`,
} as const;
7 changes: 7 additions & 0 deletions starterkits/saas/src/app/auth/login/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { AuthForm } from "@/app/auth/_components/auth-form";
import { loginPageConfig } from "@/app/auth/login/_constants/page-config";
import { type Metadata } from "next";

export const metadata: Metadata = {
title: loginPageConfig.title,
description: loginPageConfig.description,
};

export default function Login() {
return <AuthForm type="login" />;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { siteConfig } from "@/config/site";

export const signupPageConfig = {
title: "Signup",
description: `Signup to ${siteConfig.name} to get started building your next project.`,
} as const;
7 changes: 7 additions & 0 deletions starterkits/saas/src/app/auth/signup/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { AuthForm } from "@/app/auth/_components/auth-form";
import { signupPageConfig } from "@/app/auth/signup/_constants/page-config";
import { type Metadata } from "next";

export const metadata: Metadata = {
title: signupPageConfig.title,
description: signupPageConfig.description,
};

export default function Signup() {
return <AuthForm type="signup" />;
Expand Down
24 changes: 19 additions & 5 deletions starterkits/saas/src/app/docs/[[...slug]]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { notFound } from "next/navigation";
import { Toc } from "@/components/toc";
import { getDocs } from "@/server/actions/docs";
import { type Metadata } from "next";

export const dynamic = "force-static";

Expand All @@ -10,20 +11,33 @@ type DocsSlugPageProps = {
};
};

export async function generateMetadata({
params,
}: DocsSlugPageProps): Promise<Metadata> {
const slug = Array.isArray(params.slug) ? `/${params.slug.join("/")}` : "/";

const doc = (await getDocs()).find((doc) => doc.metaData.slug === slug);

if (!doc) {
return notFound();
}

return {
title: doc.metaData.title,
description: doc.metaData.description,
};
}

export async function generateStaticParams() {
const docs = await getDocs();

docs.map((doc) => {
console.log(doc.metaData.slug.split("/") || ["/"]);
});

return docs.map((doc) => ({
slug: doc.metaData.slug.split("/") || ["/"],
}));
}

export default async function DocsSlugPage({ params }: DocsSlugPageProps) {
const slug = Array.isArray(params.slug) ? params.slug.join("/") : "/";
const slug = Array.isArray(params.slug) ? `/${params.slug.join("/")}` : "/";

const doc = (await getDocs()).find((doc) => doc.metaData.slug === slug);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const invitePageConfig = {
title: ({ orgName }: { orgName: string }) => `Invite to ${orgName}`,
description: ({ orgName }: { orgName: string }) =>
`Invite your team to ${orgName} and get started building your next project.`,
} as const;
18 changes: 17 additions & 1 deletion starterkits/saas/src/app/invite/org/[orgId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { getOrgByIdQuery } from "@/server/actions/organization/queries";
import { RequestCard } from "@/app/invite/org/[orgId]/_components/request-card";
import { notFound } from "next/navigation";
import { type Metadata } from "next";

type OrgRequestProps = {
export type OrgRequestProps = {
params: {
orgId: string;
};
Expand All @@ -23,3 +24,18 @@ export default async function OrgRequestPage({
</main>
);
}

export async function generateMetadata({
params,
}: OrgRequestProps): Promise<Metadata> {
const org = await getOrgByIdQuery({ orgId: params.orgId });

if (!org) {
return notFound();
}

return {
title: `Invite to ${org.name}`,
description: `Invite your team to ${org.name} and get started building your next project.`,
};
}
19 changes: 14 additions & 5 deletions starterkits/saas/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@ import { Toaster } from "@/components/ui/sonner";
import "@/styles/globals.css";
import "@/styles/prism.css";
import { fontHeading, fontSans } from "@/lib/fonts";
import { type Metadata } from "next";
import {
defaultMetadata,
twitterMetadata,
ogMetadata,
} from "@/app/shared-metadata";

export const metadata = {
title: "RapidLaunch - Next.js Boilerplate",
description:
"Next.js boilerplate with shadcn ui, TRPC, TailwindCSS, and Drizzle.",
icons: [{ rel: "icon", url: "/favicon.ico" }],
export const metadata: Metadata = {
...defaultMetadata,
twitter: {
...twitterMetadata,
},
openGraph: {
...ogMetadata,
},
};

export default function RootLayout({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const maintenancePageConfig = {
title: "Maintenance",
description:
"We&apos;re currently undergoing maintenance. Please check back later.",
} as const;
7 changes: 7 additions & 0 deletions starterkits/saas/src/app/maintenance/page.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { maintenancePageConfig } from "@/app/maintenance/_constants/page-config";
import { siteConfig } from "@/config/site";
import { type Metadata } from "next";

export const metadata: Metadata = {
title: maintenancePageConfig.title,
description: maintenancePageConfig.description,
};

export default function Maintenance() {
return (
Expand Down
39 changes: 39 additions & 0 deletions starterkits/saas/src/app/shared-metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { siteConfig } from "@/config/site";
import { siteUrls } from "@/config/urls";
import type { Metadata } from "next";

export const defaultMetadata: Metadata = {
title: {
template: `%s | ${siteConfig.name}`,
default: siteConfig.name,
},
description: siteConfig.description,
metadataBase: new URL(siteUrls.publicUrl),
keywords: [
"Next.js",
"React",
"Next.js Starter kit",
"SaaS Starter Kit",
"Shadcn UI",
],
authors: [{ name: "Ali Farooq", url: "https://twitter.com/alifarooqdev" }],
creator: "AliFarooqDev",
};

export const twitterMetadata: Metadata["twitter"] = {
title: siteConfig.name,
description: siteConfig.description,
card: "summary_large_image",
images: [siteConfig.orgImage],
creator: "@alifarooqdev",
};

export const ogMetadata: Metadata["openGraph"] = {
title: siteConfig.name,
description: siteConfig.description,
type: "website",
images: [{ url: siteConfig.orgImage, alt: siteConfig.name }],
locale: "en_US",
url: siteUrls.publicUrl,
siteName: siteConfig.name,
};
29 changes: 29 additions & 0 deletions starterkits/saas/src/app/sitemap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { publicRoutes, siteUrls } from "@/config/urls";
import { getBlogs } from "@/server/actions/blog";
import { getDocs } from "@/server/actions/docs";
import type { MetadataRoute } from "next";

const addPathToBaseURL = (path: string) => `${siteUrls.publicUrl}${path}`;

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const allBlogs = await getBlogs();

const blogs = allBlogs.map((blog) => ({
url: addPathToBaseURL(`/${blog.metaData.slug}`),
lastModified: new Date(blog.metaData.updatedAt),
}));

const allDocs = await getDocs();

const docs = allDocs.map((doc) => ({
url: addPathToBaseURL(`/${doc.metaData.slug}`),
lastModified: new Date(doc.metaData.publishedAt),
}));

const routes = publicRoutes.map((route) => ({
url: addPathToBaseURL(route),
lastModified: new Date(),
}));

return [...routes, ...blogs, ...docs];
}
Loading

0 comments on commit 787142c

Please sign in to comment.