Skip to content

Commit

Permalink
feat/metadata
Browse files Browse the repository at this point in the history
Add useful metadata and favicons for SEO.
  • Loading branch information
rikhall1515 authored Apr 19, 2024
2 parents 81ac7c0 + d48bb83 commit 166b934
Show file tree
Hide file tree
Showing 26 changed files with 426 additions and 3 deletions.
57 changes: 57 additions & 0 deletions app/(public)/sign-in/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Metadata } from "next";
import Image from "next/image";
import Link from "next/link";
import { redirect } from "next/navigation";
Expand All @@ -6,7 +7,63 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { createClient } from "@/db/server";
import { env } from "@/env/client";

export const metadata: Metadata = {
title: "Sign In",
alternates: {
canonical: "/sign-in",
},
icons: {
apple: "/static/favicon/apple-touch-icon.png",
other: [
{
rel: "alternate icon",
sizes: "48x48",
url: "/static/favicon/favicon.ico",
},
{
rel: "icon",
type: "image/svg+xml",
sizes: "any",
url: "/static/favicon/favicon.svg",
},
{
rel: "icon",
type: "image/png",
sizes: "32x32",
url: "/static/favicon/favicon-32x32.png",
},
{
rel: "icon",
type: "image/png",
sizes: "16x16",
url: "/static/favicon/favicon-16x16.png",
},
{
rel: "mask-icon",
color: "#0e0813",
url: "/public/static/favicon/safari-pinned-tab.svg",
},
],
},
openGraph: {
title: "Sign In - rikhall.proj",
description: "The sign in page for the NextJS template.",
url: env.NEXT_PUBLIC_BASE_URL,
images: "/next-data/og?title=Sign%20In",
siteName: "RikardTemplate",
locale: "en_US",
type: "website",
},
twitter: {
title: "Sign In - rikhall.proj",
description: "The sign in page for the NextJS template.",
images: "/next-data/og?title=Sign%20In",
card: "summary_large_image",
creator: "@rikhall_",
},
};
export default function SignIn() {
const signIn = async (formData: FormData) => {
"use server";
Expand Down
58 changes: 58 additions & 0 deletions app/(public)/sign-up/page.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { Metadata } from "next";
import { headers } from "next/headers";
import Image from "next/image";
import Link from "next/link";
Expand All @@ -7,6 +8,63 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { createClient } from "@/db/server";
import { env } from "@/env/client";

export const metadata: Metadata = {
title: "Sign Up",
alternates: {
canonical: "/sign-in",
},
icons: {
apple: "/static/favicon/apple-touch-icon.png",
other: [
{
rel: "alternate icon",
sizes: "48x48",
url: "/static/favicon/favicon.ico",
},
{
rel: "icon",
type: "image/svg+xml",
sizes: "any",
url: "/static/favicon/favicon.svg",
},
{
rel: "icon",
type: "image/png",
sizes: "32x32",
url: "/static/favicon/favicon-32x32.png",
},
{
rel: "icon",
type: "image/png",
sizes: "16x16",
url: "/static/favicon/favicon-16x16.png",
},
{
rel: "mask-icon",
color: "#0e0813",
url: "/public/static/favicon/safari-pinned-tab.svg",
},
],
},
openGraph: {
title: "Sign Up - rikhall.proj",
description: "Register an account with the NextJS template.",
url: env.NEXT_PUBLIC_BASE_URL,
images: "/next-data/og?title=Sign%20Up",
siteName: "RikardTemplate",
locale: "en_US",
type: "website",
},
twitter: {
title: "Sign Up - rikhall.proj",
description: "Register an account with the NextJS template.",
images: "/next-data/og?title=Sign%20Up",
card: "summary_large_image",
creator: "@rikhall_",
},
};

export default function Component() {
const signUp = async (formData: FormData) => {
Expand Down
Binary file removed app/favicon.ico
Binary file not shown.
21 changes: 18 additions & 3 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,29 @@ import { Analytics } from "@vercel/analytics/react";
import { SpeedInsights } from "@vercel/speed-insights/next";
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";

import "./globals.css";
import { env } from "@/env/client";
import { VERCEL_ENV } from "@/next.constants.mjs";
const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
metadataBase: new URL(env.NEXT_PUBLIC_BASE_URL),
title: {
template: "%s | rikhall.proj",
default: "NextJS Template | rikhall.proj",
},
description: "This is a Next.JS template made by Rikard Hallberg.",
manifest: "/site.webmanifest",
creator: "Rikard Hallberg",
publisher: "Vercel",
referrer: "origin-when-cross-origin",
generator: "Next.js",
applicationName: "rikhall.proj",
authors: [{ name: "Rikard Hallberg", url: "https://rikardhallberg.com" }],
other: {
"msapplication-TileColor": "#0e0813",
},
};

export default function RootLayout({
Expand Down
65 changes: 65 additions & 0 deletions app/next-data/og/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { ImageResponse } from "next/og";

// import HexagonGrid from "@/components/Icons/HexagonGrid";
// import JsIconWhite from "@/components/Icons/Logos/JsIconWhite";

import { VERCEL_ENV, VERCEL_REVALIDATE } from "@/next.constants.mjs";

// This is the Route Handler for the `GET` method which handles the request
// for generating OpenGrapgh images for Blog Posts and Pages
// @see https://nextjs.org/docs/app/building-your-application/routing/router-handlers
export const GET = async (request: Request) => {
const { searchParams } = new URL(request.url);

// ?title=<title>
const hasTitle = searchParams.has("title");
const title = hasTitle
? searchParams.get("title")?.slice(0, 100)
: "Next.js Project Template";
return new ImageResponse(
(
<div tw="relative flex items-center justify-center bg-black w-[1200px] h-[600px]">
<div tw="absolute mx-auto flex max-w-xl flex-col text-center items-center text-3xl font-semibold text-white">
<svg
xmlns="http://www.w3.org/2000/svg"
width="128"
height="128"
fill="none"
>
<path
fill="currentColor"
fillRule="evenodd"
d="M0 0h14c2.122 0 4.157 1.054 5.657 2.929C21.157 4.804 22 7.348 22 10s-.843 5.196-2.343 7.071S16.122 20 14 20l2.667 4h4.668L19 19.997c1.227-.914 2.402-2.063 3.477-4.286L32 31.999h-6L23.668 28h-4.335L22 32h-6L8 20H6v12H0V0Zm12 14a4 4 0 0 0 0-8H6v8h6Z"
clipRule="evenodd"
/>
</svg>
<h1 tw="font-bold" style={{ fontWeight: 700 }}>
{title}
</h1>
</div>
</div>
),
{
width: 1200,
height: 600,
}
);
};

// We want to use `edge` runtime when using Vercel
// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#runtime
export const runtime = VERCEL_ENV ? "edge" : "nodejs";

// In this case we want to catch-all possible requests. This ensures that we always generate and
// serve the OpenGrapgh images independently on the locale
// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams
export const dynamicParams = true;

// Enforces that this route is used as static rendering
// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic
export const dynamic = "auto";

// Ensures that this endpoint is invalidated and re-executed every X minutes
// so that when new deployments happen, the data is refreshed
// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#revalidate
export const revalidate = VERCEL_REVALIDATE;
61 changes: 61 additions & 0 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,66 @@
import type { Metadata } from "next";
import Image from "next/image";

import { env } from "@/env/client";

export const metadata: Metadata = {
title: "NextJS Template",
alternates: {
canonical: "/",
},
icons: {
apple: "/static/favicon/apple-touch-icon.png",
other: [
{
rel: "alternate icon",
sizes: "48x48",
url: "/static/favicon/favicon.ico",
},
{
rel: "icon",
type: "image/svg+xml",
sizes: "any",
url: "/static/favicon/favicon.svg",
},
{
rel: "icon",
type: "image/png",
sizes: "32x32",
url: "/static/favicon/favicon-32x32.png",
},
{
rel: "icon",
type: "image/png",
sizes: "16x16",
url: "/static/favicon/favicon-16x16.png",
},
{
rel: "mask-icon",
color: "#0e0813",
url: "/public/static/favicon/safari-pinned-tab.svg",
},
],
},
openGraph: {
title: "NextJS Template - rikhall.proj",
description:
"This is a Next.JS template designed and made by Rikard Hallberg.",
url: env.NEXT_PUBLIC_BASE_URL,
images: "/static/og.png",
siteName: "RikardTemplate",
locale: "en_US",
type: "website",
},
twitter: {
title: "NextJS Template - rikhall.proj",
description:
"This is a Next.JS template designed and made by Rikard Hallberg.",
images: "/static/og.png",
card: "summary_large_image",
creator: "@rikhall_",
},
};

export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
Expand Down
18 changes: 18 additions & 0 deletions app/robots.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { MetadataRoute } from "next";

// This allows us to generate a `robots.txt` file dynamically based on the needs of the Node.js Website
// @see https://nextjs.org/docs/app/api-reference/file-conventions/metadata/robots
const robots = (): MetadataRoute.Robots => ({
rules: [
{
userAgent: "*",
disallow: ["/dashboard/"],
},
],
});

export default robots;

// Enforces that this route is used as static rendering
// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic
export const dynamic = "error";
36 changes: 36 additions & 0 deletions app/sitemap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import type { MetadataRoute } from "next";

import { BASE_PATH, BASE_URL } from "@/next.constants.mjs";

// This is the combination of the Application Base URL and Base PATH
const baseUrlAndPath = `${BASE_URL}${BASE_PATH}`;

// This allows us to generate a `sitemap.xml` file dynamically based on the needs of the Node.js Website
// Next.js Sitemap Generation doesn't support `alternate` refs yet
// @see https://github.com/vercel/next.js/discussions/55646
const sitemap = async (): Promise<MetadataRoute.Sitemap> => {
const staticUrls = [
"",
"legal/terms",
"legal/support-terms",
"legal/sla",
"legal/privacy-policy",
"sign-in",
"sign-up",
"about",
"help",
];
const currentDate = new Date().toISOString();

return [...staticUrls].map((route) => ({
url: `${baseUrlAndPath}${route}`,
lastModified: currentDate,
changeFrequency: "always",
}));
};

export default sitemap;

// Enforces that this route is used as static rendering
// @see https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamic
export const dynamic = "error";
10 changes: 10 additions & 0 deletions next.constants.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,13 @@ export const THEME_STORAGE_KEY = "theme";
* Note that this is a custom Environment Variable that can be defined by us when necessary
*/
export const BASE_PATH = process.env.NEXT_PUBLIC_BASE_PATH || "";

/**
* This is used for defining a default time of when `next-data` and other dynamically generated
* but static-enabled pages should be regenerated.
*
* Note that this is a custom Environment Variable that can be defined by us when necessary
*/
export const VERCEL_REVALIDATE = Number(
process.env.NEXT_PUBLIC_VERCEL_REVALIDATE_TIME || 300
);
9 changes: 9 additions & 0 deletions public/browserconfig.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/static/favicon/mstile-150x150.png"/>
<TileColor>#0e0813</TileColor>
</tile>
</msapplication>
</browserconfig>
2 changes: 2 additions & 0 deletions public/security.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Contact: [email protected]
Policy: https://github.com/rikhall1515/nextjs-project-template/security
Loading

0 comments on commit 166b934

Please sign in to comment.