diff --git a/app/(public)/sign-in/page.tsx b/app/(public)/sign-in/page.tsx
index 8cf2ff6..6863dd7 100644
--- a/app/(public)/sign-in/page.tsx
+++ b/app/(public)/sign-in/page.tsx
@@ -1,3 +1,4 @@
+import type { Metadata } from "next";
import Image from "next/image";
import Link from "next/link";
import { redirect } from "next/navigation";
@@ -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";
diff --git a/app/(public)/sign-up/page.tsx b/app/(public)/sign-up/page.tsx
index 3838dc7..d167008 100644
--- a/app/(public)/sign-up/page.tsx
+++ b/app/(public)/sign-up/page.tsx
@@ -1,3 +1,4 @@
+import type { Metadata } from "next";
import { headers } from "next/headers";
import Image from "next/image";
import Link from "next/link";
@@ -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) => {
diff --git a/app/favicon.ico b/app/favicon.ico
deleted file mode 100644
index 718d6fe..0000000
Binary files a/app/favicon.ico and /dev/null differ
diff --git a/app/layout.tsx b/app/layout.tsx
index f0f9e62..14b186a 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -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({
diff --git a/app/next-data/og/route.tsx b/app/next-data/og/route.tsx
new file mode 100644
index 0000000..c22b680
--- /dev/null
+++ b/app/next-data/og/route.tsx
@@ -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=
+ const hasTitle = searchParams.has("title");
+ const title = hasTitle
+ ? searchParams.get("title")?.slice(0, 100)
+ : "Next.js Project Template";
+ return new ImageResponse(
+ (
+
+ ),
+ {
+ 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;
diff --git a/app/page.tsx b/app/page.tsx
index 5e09f81..0d3e210 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -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 (
diff --git a/app/robots.ts b/app/robots.ts
new file mode 100644
index 0000000..7f1b5dc
--- /dev/null
+++ b/app/robots.ts
@@ -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";
diff --git a/app/sitemap.ts b/app/sitemap.ts
new file mode 100644
index 0000000..67cb259
--- /dev/null
+++ b/app/sitemap.ts
@@ -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 => {
+ 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";
diff --git a/next.constants.mjs b/next.constants.mjs
index deb33fa..331c264 100644
--- a/next.constants.mjs
+++ b/next.constants.mjs
@@ -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
+);
diff --git a/public/browserconfig.xml b/public/browserconfig.xml
new file mode 100644
index 0000000..38fd0ab
--- /dev/null
+++ b/public/browserconfig.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+ #0e0813
+
+
+
diff --git a/public/security.txt b/public/security.txt
new file mode 100644
index 0000000..cd1e69b
--- /dev/null
+++ b/public/security.txt
@@ -0,0 +1,2 @@
+Contact: r15.hallberg@gmail.com
+Policy: https://github.com/rikhall1515/nextjs-project-template/security
\ No newline at end of file
diff --git a/public/site.webmanifest b/public/site.webmanifest
new file mode 100644
index 0000000..e6648e6
--- /dev/null
+++ b/public/site.webmanifest
@@ -0,0 +1,23 @@
+{
+ "name": "NextJS Template - rikhall.proj",
+ "short_name": "rikhall1515_template",
+ "icons": [
+ {
+ "src": "/static/favicon/android-chrome-192x192.png",
+ "sizes": "192x192",
+ "type": "image/png",
+ "purpose": "maskable any"
+ },
+ {
+ "src": "/static/favicon/android-chrome-512x512.png",
+ "sizes": "512x512",
+ "type": "image/png",
+ "purpose": "maskable any"
+ }
+ ],
+ "start_url": ".",
+ "display": "standalone",
+ "theme_color": "#0e0813",
+ "background_color": "#0e0813",
+ "description": "This is a Next.JS template designed and made by Rikard Hallberg."
+}
diff --git a/public/static/favicon/android-chrome-192x192.png b/public/static/favicon/android-chrome-192x192.png
new file mode 100644
index 0000000..96db05b
Binary files /dev/null and b/public/static/favicon/android-chrome-192x192.png differ
diff --git a/public/static/favicon/android-chrome-512x512.png b/public/static/favicon/android-chrome-512x512.png
new file mode 100644
index 0000000..b2254ea
Binary files /dev/null and b/public/static/favicon/android-chrome-512x512.png differ
diff --git a/public/static/favicon/apple-touch-icon.png b/public/static/favicon/apple-touch-icon.png
new file mode 100644
index 0000000..9836efb
Binary files /dev/null and b/public/static/favicon/apple-touch-icon.png differ
diff --git a/public/static/favicon/favicon-16x16.png b/public/static/favicon/favicon-16x16.png
new file mode 100644
index 0000000..518ef32
Binary files /dev/null and b/public/static/favicon/favicon-16x16.png differ
diff --git a/public/static/favicon/favicon-32x32.png b/public/static/favicon/favicon-32x32.png
new file mode 100644
index 0000000..9ca9614
Binary files /dev/null and b/public/static/favicon/favicon-32x32.png differ
diff --git a/public/static/favicon/favicon.ico b/public/static/favicon/favicon.ico
new file mode 100644
index 0000000..5884ad7
Binary files /dev/null and b/public/static/favicon/favicon.ico differ
diff --git a/public/static/favicon/favicon.svg b/public/static/favicon/favicon.svg
new file mode 100644
index 0000000..2b25e01
--- /dev/null
+++ b/public/static/favicon/favicon.svg
@@ -0,0 +1,30 @@
+
diff --git a/public/static/favicon/mstile-144x144.png b/public/static/favicon/mstile-144x144.png
new file mode 100644
index 0000000..b33d374
Binary files /dev/null and b/public/static/favicon/mstile-144x144.png differ
diff --git a/public/static/favicon/mstile-150x150.png b/public/static/favicon/mstile-150x150.png
new file mode 100644
index 0000000..cfd967d
Binary files /dev/null and b/public/static/favicon/mstile-150x150.png differ
diff --git a/public/static/favicon/mstile-310x150.png b/public/static/favicon/mstile-310x150.png
new file mode 100644
index 0000000..d07ab10
Binary files /dev/null and b/public/static/favicon/mstile-310x150.png differ
diff --git a/public/static/favicon/mstile-310x310.png b/public/static/favicon/mstile-310x310.png
new file mode 100644
index 0000000..fe70f67
Binary files /dev/null and b/public/static/favicon/mstile-310x310.png differ
diff --git a/public/static/favicon/mstile-70x70.png b/public/static/favicon/mstile-70x70.png
new file mode 100644
index 0000000..ed9ab29
Binary files /dev/null and b/public/static/favicon/mstile-70x70.png differ
diff --git a/public/static/favicon/safari-pinned-tab.svg b/public/static/favicon/safari-pinned-tab.svg
new file mode 100644
index 0000000..c01faee
--- /dev/null
+++ b/public/static/favicon/safari-pinned-tab.svg
@@ -0,0 +1,39 @@
+
+
+
diff --git a/public/static/og.png b/public/static/og.png
new file mode 100644
index 0000000..179c797
Binary files /dev/null and b/public/static/og.png differ