Closed 1chooo closed 3 months ago
layout.tsx
import Script from "next/script";
import type { Metadata } from "next";
import "./globals.css";
import SideBar from "@/components/side-bar";
import NavBar from "@/components/nav-bar";
import Hello from "@/components/hello";
import { GoogleAnalytics } from '@next/third-parties/google';
const googleAnalyticId = "G-JGG75799PJ";
export const metadata: Metadata = {
title: "Hugo ChunHo Lin (1chooo) | Open Source Enthusiast",
description: "I'm Hugo ChunHo Lin, a graduate with a Bachelor's degree from National Central University (NCU) 🐿️, driven by a sincere passion for Software Engineering 💻.",
authors: [{ name: "Hugo ChunHo Lin (1chooo)" }],
keywords: ["Hugo ChunHo Lin", "1chooo", "Software Engineering", "Open Source", "NCU"],
openGraph: {
url: "https://1chooo.com/",
type: "website",
siteName: "Hugo ChunHo Lin (1chooo) | Open Source Enthusiast",
title: "Hugo ChunHo Lin (1chooo) | Open Source Enthusiast",
description: "I'm Hugo ChunHo Lin, a graduate with a Bachelor's degree from National Central University (NCU) 🐿️, driven by a sincere passion for Software Engineering 💻.",
images: [
{
url: "https://raw.githubusercontent.com/1chooo/1chooo.com/main/docs/imgs/cover_transparent_bg.png",
width: 1200,
height: 630,
alt: "Hugo ChunHo Lin (1chooo) Cover Image",
},
],
},
twitter: {
card: "summary_large_image",
title: "Hugo ChunHo Lin (1chooo) | Open Source Enthusiast",
description: "I'm Hugo ChunHo Lin, a graduate with a Bachelor's degree from National Central University (NCU) 🐿️, driven by a sincere passion for Software Engineering 💻.",
images: "https://raw.githubusercontent.com/1chooo/1chooo.com/main/docs/imgs/cover_transparent_bg.png",
},
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<head>
{/* Google Analytics */}
<Script
src="https://www.googletagmanager.com/gtag/js?id=G-JGG75799PJ"
strategy="afterInteractive"
/>
<Script id="google-analytics" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${googleAnalyticId}');
`}
</Script>
{/* Favicon and Manifest */}
<link rel="icon" href="/favicon.ico" />
<link rel="apple-touch-icon" href="/logo192.png" />
<link rel="manifest" href="/manifest.json" />
</head>
<body>
<main>
<SideBar />
<div className="main-content">
<NavBar />
{children}
</div>
</main>
<GoogleAnalytics gaId={googleAnalyticId} />
</body>
</html>
);
}
<main>
tag now wraps the primary content of your page, which is semantically correct as it identifies the main content area of the document.<main>
and the GoogleAnalytics
component.This structure ensures your page is well-organized and semantically appropriate for accessibility and SEO.
Given that the SideBar
and NavBar
components are now part of the global layout in layout.tsx
, the About
and Portfolio
components only need to focus on their specific content. Here's how you can write the About
and Portfolio
components:
'use client';
import PageContent from '@/components/page-content';
import AboutText from '@/components/about/about-text';
import GitHubStats from '@/components/about/github-stats';
import TechStack from '@/components/about/tech-stack';
import LifeStyles from '@/components/about/life-styles';
import { abouts } from '@/config/about';
const About = () => {
return (
<PageContent title={abouts.header}>
<AboutText />
<GitHubStats />
<TechStack />
<LifeStyles />
</PageContent>
);
}
export default About;
'use client';
import PageContent from '@/components/page-content';
import Projects from '@/components/portfolio/projects';
const Portfolio = () => {
return (
<PageContent title="Hugo's Portfolio">
<Projects />
</PageContent>
);
}
export default Portfolio;
PageContent Component: This is a utility component that can wrap your content, managing the page title and any other shared layout needs for individual pages. If you don't have this component yet, you can create it as follows:
import React from 'react';
import Header from '@/components/header';
const PageContent: React.FC<{ title: string; children: React.ReactNode }> = ({ title, children }) => {
return (
<article data-page={title.toLowerCase().replace(' ', '-')}>
<Header title={title} />
{children}
</article>
);
};
export default PageContent;
About Component: It now focuses purely on rendering the content relevant to the About page, without worrying about the layout structure like SideBar
or NavBar
, which are handled by layout.tsx
.
Portfolio Component: Similarly, it focuses on the Projects
component specific to the Portfolio page, wrapped inside the PageContent
for consistency.
By structuring your components this way, you maintain a clean and modular approach, allowing changes to global layout elements in layout.tsx
without affecting the individual page components.
Currently, our pages have repetitive elements. For example, in the portfolio section, we only need to modify the
<Projects />
component to display content on other pages. This means that components likeNavBar
andSideBar
are shared across all pages. To avoid duplicating code, we could incorporate these components into thelayout.tsx
file. This would streamline our layout and eliminate the need for repetitive coding.