Skip to content
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

feat: SEO - dynamic sitemap and robots.txt #32

Merged
merged 19 commits into from
Oct 23, 2024
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
26 changes: 7 additions & 19 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
{
"extends": ["next/core-web-vitals", "next/typescript", "prettier"],
"plugins": ["import"],
"extends": [
"next/core-web-vitals",
"next/typescript",
"prettier",
"plugin:jsx-a11y/recommended"
],
"rules": {
// Possible Errors
"no-console": "warn", // Warn on console usage (can change to 'error' to disallow)
Expand Down Expand Up @@ -33,22 +37,6 @@
"arrow-spacing": ["error", { "before": true, "after": true }], // Enforce spacing around arrows
"prefer-const": "error", // Prefer const for variables that are never reassigned
"no-var": "error", // Disallow var (use let or const instead)
"template-curly-spacing": ["error", "never"], // Disallow spaces inside template literals

// Import
"import/order": [
"error",
{
"groups": [
"builtin",
"external",
"internal",
"parent",
"sibling",
"index"
],
"newlines-between": "always"
}
]
"template-curly-spacing": ["error", "never"] // Disallow spaces inside template literals
}
}
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

# User generated files
public/postsData.json
10 changes: 2 additions & 8 deletions config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ author:
link: 'https://www.zla.app' # Link to your personal website or blog.
# Language setting: Use ISO 639-1 code (e.g., 'en' for English, 'zh' for Chinese)
lang: 'zh'
# Your public root url, used for SEO and meta tags. (Do not include a ending slash)
siteUrl: 'https://suzu.zla.app'

# Path to your avatar image. Can be a relative path from /public or a full URL (e.g., https://).
avatar: '/images/avatar.jpg'
Expand Down Expand Up @@ -71,14 +73,6 @@ disqusShortname: 'zla-pub'
# CUSTOM CODE BLOCKS
# ! WARNING: Only modify these if you understand the purpose of custom scripts.
#######################
# Add JavaScript URLs or code snippets to be included inside <head> on your site.
scriptSlotHeader:
-

# Add JavaScript URLs or code snippets to be included before the closing </body> tag.
scriptSlotFooter:
- 'https://cdn.jsdelivr.net/gh/zl-asica/web-cdn/js/zlasica.js'

# Add custom HTML code to be included inside the <footer> section of your site.
slotFooter: |
<!-- Add your custom footer HTML here -->
73 changes: 0 additions & 73 deletions eslint.config.mjs

This file was deleted.

48 changes: 48 additions & 0 deletions public/custom.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
'use client';

// Get the current date
function getCurrentDate() {
const date = new Date();
const formatNumber = (num) => String(num).padStart(2, '0');

const year = date.getFullYear();
const month = formatNumber(date.getMonth() + 1);
const day = formatNumber(date.getDate());
const hours = formatNumber(date.getHours());
const minutes = formatNumber(date.getMinutes());
const seconds = formatNumber(date.getSeconds());

return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

// Gray scale filter (only for /) on specific dates
function grayScale() {
// Set the date you want to gray scale
const grayScaleDates = ['04-04', '05-12', '09-18', '11-20', '12-13'];

// Get the current date
const currentDate = getCurrentDate();
const currentMonthDay = currentDate
.split(' ')[0]
.split('-')
.slice(1)
.join('-');

// Check if the current date is in the gray scale date list
if (grayScaleDates.includes(currentMonthDay)) {
// If is, set the gray scale filter
document.body.style.filter = 'grayscale(100%)';
}
}

// Custom console log
// eslint-disable-next-line no-console
console.info(
'%c由ZL Asica制作搭建与运行\nBuilt and Operated by ZL Asica\nhttps://www.zla.app',
'background:#fff;color:#000',
);

// Check if the current URL path is "/"
if (window.location.pathname === '/') {
grayScale();
}
24 changes: 0 additions & 24 deletions src/app/about/layout.tsx

This file was deleted.

27 changes: 26 additions & 1 deletion src/app/about/page.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,36 @@
import Loading from '@/app/loading';
import PostLayout from '@/components/layout/PostLayout';
import { getConfig } from '@/services/config/getConfig';
import { getPostData } from '@/services/content/posts';
import { PostData } from '@/types';
import type { Metadata } from 'next';
import { Suspense } from 'react';

export async function generateMetadata(): Promise<Metadata> {
const config = getConfig();
return {
title: `About - ${config.title}`,
description: `About page of ${config.title} - ${config.description}`,
openGraph: {
siteName: config.title,
type: 'profile',
username: config.author.name,
title: `About - ${config.title}`,
description: `About page of ${config.title} - ${config.description}`,
images: config.avatar,
url: '/about',
locale: config.lang,
},
};
}

export default async function AboutPage() {
const post: PostData = await getPostData('About', 'About');
const config = getConfig();

return <PostLayout post={post} showThumbnail={config.thumbnailAbout} />;
return (
<Suspense fallback={<Loading />}>
<PostLayout post={post} showThumbnail={config.thumbnailAbout} />
</Suspense>
);
}
36 changes: 34 additions & 2 deletions src/app/categories/[categorySlug]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import Loading from '@/app/loading';
import PostListLayout from '@/components/layout/PostListLayout';
import { getConfig } from '@/services/config/getConfig';
import { getAllPosts } from '@/services/content/posts';
import { Metadata } from 'next';
import { notFound } from 'next/navigation';
import { Suspense } from 'react';

export async function generateStaticParams() {
const config = getConfig();
Expand All @@ -10,6 +13,34 @@ export async function generateStaticParams() {
}));
}

type Props = {
params: Promise<{ categorySlug: string }>;
};

export async function generateMetadata({ params }: Props): Promise<Metadata> {
// read post slug
const category = (await params).categorySlug;

const config = getConfig();

// Find the category based on the slug from params
const categoryData = config.postCategories.find(
(cat) => cat.slug === category,
) || { name: 'Not Found' };
return {
title: `分类:${categoryData.name} - ${config.title}`,
openGraph: {
siteName: config.title,
title: `分类:${categoryData.name} - ${config.title}`,
description: `分类:${categoryData.name} - ${config.description}`,
url: `/categories/${category}`,
images: config.avatar,
type: 'website',
locale: config.lang,
},
};
}

export default async function CategoryPage(props: {
params: Promise<{ categorySlug: string }>;
}) {
Expand All @@ -35,8 +66,9 @@ export default async function CategoryPage(props: {
return (
<div className='container mx-auto p-4'>
<h1 className='mb-6 text-center text-4xl font-bold'>{category.name}</h1>

<PostListLayout posts={filteredPosts} />
<Suspense fallback={<Loading />}>
<PostListLayout posts={filteredPosts} />
</Suspense>
</div>
);
}
24 changes: 0 additions & 24 deletions src/app/friends/layout.tsx

This file was deleted.

26 changes: 25 additions & 1 deletion src/app/friends/page.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
import Loading from '@/app/loading';
import PostLayout from '@/components/layout/PostLayout';
import { getConfig } from '@/services/config/getConfig';
import { getPostData } from '@/services/content/posts';
import '@/styles/friendsLinks.css';
import { PostData } from '@/types';
import type { Metadata } from 'next';
import { Suspense } from 'react';

export async function generateMetadata(): Promise<Metadata> {
const config = getConfig();
return {
title: `Friends - ${config.title}`,
description: `Friends page of ${config.title} - ${config.description}`,
openGraph: {
siteName: config.title,
title: `Friends - ${config.title}`,
description: `Friends page of ${config.title} - ${config.description}`,
url: '/friends',
images: config.avatar,
type: 'website',
locale: config.lang,
},
};
}

export default async function FriendsPage() {
const post: PostData = await getPostData('Friends', 'Friends');
const config = getConfig();

return <PostLayout post={post} showThumbnail={config.thumbnailFriends} />;
return (
<Suspense fallback={<Loading />}>
<PostLayout post={post} showThumbnail={config.thumbnailFriends} />
</Suspense>
);
}
11 changes: 0 additions & 11 deletions src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,6 @@ h4 {
margin-block-end: 1.33em;
}

/* code {
background: #1d1f21;
color: #fff;
word-break: break-word;
font-family: 'Source Code Pro', monospace, Helvetica, Tahoma, Arial, STXihei,
'STHeiti Light', 'Microsoft YaHei', sans-serif;
padding: 2px;
text-shadow: none;
border-radius: 0 0 5px 5px;
} */

/****************************************************
* IMAGES & MEDIA
****************************************************/
Expand Down
Loading
Loading