作者 xiaoqiu

使用AI帮忙优化了seo

# API地址
NUXT_API_URL="http://htai.aiboxgo.com"
NUXT_BASE_URL="http://htai.aiboxgo.com"
\ No newline at end of file
NUXT_BASE_URL="https://www.aiboxgo.com"
\ No newline at end of file
... ...
不能预览此文件类型
... ... @@ -10,6 +10,7 @@
height="30"
src="../../assets/Annie-logo.jpg"
alt="Annie-logo"
fetchpriority="high"
/>
<h1 style="font-size: 0px">
{{ webSite.webname }}
... ...
... ... @@ -52,6 +52,7 @@ export default defineNuxtConfig({
app: {
head: {
title: 'Annie网站 - 优质 AI 工具集合、AI 资源网站、AI 导航平台',
titleTemplate: '%s | Annie网站',
htmlAttrs: {
lang: 'zh-CN'
},
... ... @@ -61,12 +62,22 @@ export default defineNuxtConfig({
{ name: "force-rendering", content: "webkit"},
{ "http-equiv":"X-UA-Compatible", content:"IE=edge, chrome=1" },
{ name: 'viewport', content:"width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" },
{ name:'robots', content:'max-image-preview:large'}
{ name: 'description', content: 'Annie网站是专业的AI工具导航平台,汇集全网优质AI工具,包含AI写作、AI绘画、AI视频、AI对话、AI代码、AI设计、AI办公等各类AI资源,让你快速找到好用的AI工具。' },
{ name: 'keywords', content: 'AI工具,AI导航,AI资源,AI写作,AI绘画,AI视频,AI对话,ChatGPT,AI代码,AI设计,人工智能工具' },
{ name: 'author', content: 'Annie网站' },
{ name:'robots', content:'index, follow, max-image-preview:large, max-snippet:-1, max-video-preview:-1'},
{ name: 'googlebot', content: 'index, follow' },
{ name: 'format-detection', content: 'telephone=no' },
{ name: 'referrer', content: 'origin-when-cross-origin' },
{ property: 'og:type', content: 'website' },
{ property: 'og:site_name', content: 'Annie网站' },
{ property: 'og:locale', content: 'zh_CN' },
{ property: 'twitter:card', content: 'summary_large_image' },
{ property: 'twitter:site', content: '@Annie网站' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
{ rel: 'canonical', href: 'https://aiboxgo.com/' }
],
script: [{ src: "/js/translate.js"}]
},
... ...
... ... @@ -24,9 +24,12 @@
import type { appType } from "~/api/types/app";
import { getAppList } from "~/api/app";
import type { classifyType } from "~/api/types/classify";
import type { webSiteType } from "~/api/types/webSite";
const sortList = useState<classifyType[]>("sortTree");
const webSite = useState<webSiteType>("webSite");
const route = useRoute();
const router = useRouter();
const config = useRuntimeConfig();
const { name } = route.params;
const list = ref<appType[]>([]);
const total = ref<number>(0);
... ... @@ -36,7 +39,6 @@ const params = ref<any>({
typeAlias: name as string,
});
// 返回分类名称
function findLabelByAlias<
T extends { alias?: string; label?: string; children?: T[] }
>(alias: string, data: T[], childrenKey: string = "children"): string {
... ... @@ -44,14 +46,12 @@ function findLabelByAlias<
return "";
}
// 1. 首先在当前层级查找
for (const item of data) {
if (item.alias === alias) {
return item.label || ""; // 返回 label 或空字符串
return item.label || "";
}
}
// 2. 如果当前层级没找到,递归查找子节点
for (const item of data) {
const children = (item as any)[childrenKey] as T[];
if (children && children.length > 0) {
... ... @@ -65,6 +65,8 @@ function findLabelByAlias<
return "";
}
const categoryLabel = findLabelByAlias(name as string, sortList.value);
function onPageChange(pageNum: number) {
router.push({
path: route.path + "/page/" + pageNum,
... ... @@ -74,4 +76,72 @@ function onPageChange(pageNum: number) {
const res = await getAppList(params.value);
list.value = res.rows;
total.value = res.total;
useHead({
title: `${categoryLabel} - ${webSite.value.webname}`,
meta: [
{
name: "description",
content: `${categoryLabel}分类下的AI工具推荐,精选优质${categoryLabel}相关AI工具,助您高效完成工作。`,
},
{
name: "keywords",
content: `${categoryLabel},AI工具,${categoryLabel}AI,人工智能,${webSite.value.webkeywords}`,
},
{ name: "robots", content: "index, follow" },
{
property: "og:title",
content: `${categoryLabel} - ${webSite.value.webname}`,
},
{
property: "og:description",
content: `${categoryLabel}分类下的AI工具推荐,精选优质${categoryLabel}相关AI工具。`,
},
{ property: "og:type", content: "website" },
{ property: "og:url", content: config.public.baseUrl + route.fullPath },
{ property: "og:site_name", content: webSite.value.webname },
],
link: [{ rel: "canonical", href: config.public.baseUrl + route.fullPath }],
script: [
{
type: "application/ld+json",
children: JSON.stringify({
"@context": "https://schema.org",
"@graph": [
{
"@type": "CollectionPage",
"@id": config.public.baseUrl + route.fullPath + "#collectionpage",
url: config.public.baseUrl + route.fullPath,
name: `${categoryLabel} - ${webSite.value.webname}`,
description: `${categoryLabel}分类下的AI工具推荐`,
isPartOf: {
"@id": "https://aiboxgo.com/#website",
},
about: {
"@type": "Thing",
name: categoryLabel,
},
},
{
"@type": "BreadcrumbList",
"@id": config.public.baseUrl + route.fullPath + "#breadcrumb",
itemListElement: [
{
"@type": "ListItem",
position: 1,
name: "首页",
item: "https://aiboxgo.com/",
},
{
"@type": "ListItem",
position: 2,
name: categoryLabel,
},
],
},
],
}),
},
],
});
</script>
... ...
... ... @@ -23,9 +23,12 @@
import type { appType } from "~/api/types/app";
import { getAppList } from "~/api/app";
import type { classifyType } from "~/api/types/classify";
import type { webSiteType } from "~/api/types/webSite";
const sortList = useState<classifyType[]>("sortTree");
const webSite = useState<webSiteType>("webSite");
const route = useRoute();
const router = useRouter();
const config = useRuntimeConfig();
const { pageNum, name } = route.params;
const list = ref<appType[]>([]);
const total = ref<number>(0);
... ... @@ -35,7 +38,6 @@ const params = ref<any>({
typeAlias: name as string,
});
// 返回分类名称
function findLabelByAlias<
T extends { alias?: string; label?: string; children?: T[] }
>(alias: string, data: T[], childrenKey: string = "children"): string {
... ... @@ -43,14 +45,12 @@ function findLabelByAlias<
return "";
}
// 1. 首先在当前层级查找
for (const item of data) {
if (item.alias === alias) {
return item.label || ""; // 返回 label 或空字符串
return item.label || "";
}
}
// 2. 如果当前层级没找到,递归查找子节点
for (const item of data) {
const children = (item as any)[childrenKey] as T[];
if (children && children.length > 0) {
... ... @@ -64,8 +64,9 @@ function findLabelByAlias<
return "";
}
const categoryLabel = findLabelByAlias(name as string, sortList.value);
function onPageChange(pageNum: number) {
console.log(route);
if (pageNum === 1) {
router.push({
path: "/category/" + name,
... ... @@ -80,4 +81,31 @@ function onPageChange(pageNum: number) {
const res = await getAppList(params.value);
list.value = res.rows;
total.value = res.total;
useHead({
title: `${categoryLabel} - 第${pageNum}页 - ${webSite.value.webname}`,
meta: [
{
name: "description",
content: `${categoryLabel}分类下的AI工具推荐第${pageNum}页,精选优质${categoryLabel}相关AI工具。`,
},
{
name: "keywords",
content: `${categoryLabel},AI工具,${categoryLabel}AI,人工智能,第${pageNum}页`,
},
{ name: "robots", content: "index, follow" },
{
property: "og:title",
content: `${categoryLabel} - 第${pageNum}页 - ${webSite.value.webname}`,
},
{
property: "og:description",
content: `${categoryLabel}分类下的AI工具推荐第${pageNum}页。`,
},
{ property: "og:type", content: "website" },
{ property: "og:url", content: config.public.baseUrl + route.fullPath },
{ property: "og:site_name", content: webSite.value.webname },
],
link: [{ rel: "canonical", href: config.public.baseUrl + route.fullPath }],
});
</script>
... ...
... ... @@ -27,7 +27,6 @@ useHead({
meta: [
{ name: "description", content: webSite.value.webdescription },
{ name: "keywords", content: webSite.value.webkeywords },
{ name: "format-detection", content: "telephone=no" },
{ name: "referrer", content: "origin-when-cross-origin" },
{
... ... @@ -45,7 +44,6 @@ useHead({
content:
"专业 AI 工具导航网站,汇集全网优质 AI 工具,包含 AI 写作、AI 绘画、AI 视频、AI 对话、AI 代码、AI 设计、AI 办公等各类 AI 资源,让你快速找到好用的 AI 工具。",
},
// { property: 'og:image', content: 'https://aiboxgo.com/images/logo.png'},
{ property: "og:url", content: "https://aiboxgo.com/" },
{ property: "og:site_name", content: "Annie网站" },
{ property: "og:type", content: "website" },
... ... @@ -60,6 +58,56 @@ useHead({
"专业 AI 工具导航网站,汇集全网优质 AI 工具,包含 AI 写作、AI 绘画、AI 视频、AI 对话、AI 代码、AI 设计、AI 办公等各类 AI 资源,让你快速找到好用的 AI 工具。",
},
],
script: [
{
type: "application/ld+json",
children: JSON.stringify({
"@context": "https://schema.org",
"@graph": [
{
"@type": "WebSite",
"@id": "https://aiboxgo.com/#website",
"url": "https://aiboxgo.com/",
"name": webSite.value.webname,
"description": webSite.value.webdescription,
"inLanguage": "zh-CN",
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://aiboxgo.com/search?keyword={search_term_string}"
},
"query-input": "required name=search_term_string"
}
},
{
"@type": "Organization",
"@id": "https://aiboxgo.com/#organization",
"name": webSite.value.webname,
"url": "https://aiboxgo.com/",
"logo": {
"@type": "ImageObject",
"url": "https://aiboxgo.com/favicon.ico"
},
"sameAs": []
},
{
"@type": "CollectionPage",
"@id": "https://aiboxgo.com/",
"url": "https://aiboxgo.com/",
"name": webSite.value.webname,
"description": webSite.value.webdescription,
"isPartOf": {
"@id": "https://aiboxgo.com/#website"
},
"about": {
"@id": "https://aiboxgo.com/#organization"
}
}
]
})
}
]
});
</script>
... ...
... ... @@ -19,9 +19,12 @@
<script lang="ts" setup>
import type { appType } from "~/api/types/app";
import { getAppList } from "~/api/app";
import type { webSiteType } from "~/api/types/webSite";
const route = useRoute();
const router = useRouter();
const config = useRuntimeConfig();
const webSite = useState<webSiteType>("webSite");
const { keyword } = route.query as { keyword: string };
const list = ref<appType[]>([]);
... ... @@ -44,4 +47,21 @@ function onPageChange(pageNum: number) {
const res = await getAppList(params.value);
list.value = res.rows;
total.value = res.total;
useHead({
title: `"${keyword}" 搜索结果 - ${webSite.value.webname}`,
meta: [
{ name: "description", content: `搜索"${keyword}"相关的AI工具,找到${total.value}个结果。${webSite.value.webdescription}` },
{ name: "keywords", content: `${keyword},AI工具搜索,${webSite.value.webkeywords}` },
{ name: "robots", content: "noindex, follow" },
{ property: "og:title", content: `"${keyword}" 搜索结果 - ${webSite.value.webname}` },
{ property: "og:description", content: `搜索"${keyword}"相关的AI工具结果页面。` },
{ property: "og:type", content: "website" },
{ property: "og:url", content: config.public.baseUrl + route.fullPath },
{ property: "og:site_name", content: webSite.value.webname },
],
link: [
{ rel: "canonical", href: config.public.baseUrl + route.fullPath }
]
});
</script>
... ...
... ... @@ -22,8 +22,11 @@
<script lang="ts" setup>
import type { appType } from "~/api/types/app";
import { getAppList } from "~/api/app";
import type { webSiteType } from "~/api/types/webSite";
const route = useRoute();
const router = useRouter();
const config = useRuntimeConfig();
const webSite = useState<webSiteType>("webSite");
const { pageNum } = route.params;
const { keyword } = route.query as { keyword: string };
const list = ref<appType[]>([]);
... ... @@ -54,4 +57,21 @@ function onPageChange(pageNum: number) {
const res = await getAppList(params.value);
list.value = res.rows;
total.value = res.total;
useHead({
title: `"${keyword}" 搜索结果 - 第${pageNum}页 - ${webSite.value.webname}`,
meta: [
{ name: "description", content: `搜索"${keyword}"相关的AI工具第${pageNum}页结果。` },
{ name: "keywords", content: `${keyword},AI工具搜索,第${pageNum}页` },
{ name: "robots", content: "noindex, follow" },
{ property: "og:title", content: `"${keyword}" 搜索结果 - 第${pageNum}页 - ${webSite.value.webname}` },
{ property: "og:description", content: `搜索"${keyword}"相关的AI工具第${pageNum}页结果。` },
{ property: "og:type", content: "website" },
{ property: "og:url", content: config.public.baseUrl + route.fullPath },
{ property: "og:site_name", content: webSite.value.webname },
],
link: [
{ rel: "canonical", href: config.public.baseUrl + route.fullPath }
]
});
</script>
... ...
... ... @@ -58,6 +58,13 @@ useHead({
meta: [
{ name: "description", content: DetailData.value.description },
{
name: "keywords",
content: `${DetailData.value.title},AI工具,${
DetailData.value.types?.map((t: any) => t.label).join(",") || ""
}`,
},
{ name: "robots", content: "index, follow" },
{
property: "og:title",
content: `${DetailData.value.title}${
DetailData.value.popupContent != null
... ... @@ -81,6 +88,13 @@ useHead({
property: "article:published_time",
content: DetailData.value.updateTime,
},
{ property: "twitter:card", content: "summary_large_image" },
{ property: "twitter:title", content: DetailData.value.title },
{ property: "twitter:description", content: DetailData.value.description },
{
property: "twitter:image",
content: config.public.baseUrl + DetailData.value.image,
},
],
link: [
{
... ... @@ -88,6 +102,77 @@ useHead({
href: config.public.baseUrl + route.fullPath,
},
],
script: [
{
type: "application/ld+json",
children: JSON.stringify({
"@context": "https://schema.org",
"@graph": [
{
"@type": "SoftwareApplication",
"@id": config.public.baseUrl + route.fullPath + "#software",
name: DetailData.value.title,
description: DetailData.value.description,
url: DetailData.value.link,
image: config.public.baseUrl + DetailData.value.image,
applicationCategory: "UtilitiesApplication",
operatingSystem: "Web Browser",
offers: {
"@type": "Offer",
price: "0",
priceCurrency: "CNY",
},
},
{
"@type": "Article",
"@id": config.public.baseUrl + route.fullPath + "#article",
headline: DetailData.value.title,
description: DetailData.value.description,
image: config.public.baseUrl + DetailData.value.image,
datePublished: DetailData.value.updateTime,
dateModified: DetailData.value.updateTime,
author: {
"@id": "https://aiboxgo.com/#organization",
},
publisher: {
"@id": "https://aiboxgo.com/#organization",
},
mainEntityOfPage: {
"@type": "WebPage",
"@id": config.public.baseUrl + route.fullPath,
},
},
{
"@type": "BreadcrumbList",
"@id": config.public.baseUrl + route.fullPath + "#breadcrumb",
itemListElement: [
{
"@type": "ListItem",
position: 1,
name: "首页",
item: "https://aiboxgo.com/",
},
...(DetailData.value.types?.[0]
? [
{
"@type": "ListItem",
position: 2,
name: DetailData.value.types[0].label,
item: `https://aiboxgo.com/category/${DetailData.value.types[0].alias}`,
},
]
: []),
{
"@type": "ListItem",
position: DetailData.value.types?.length ? 3 : 2,
name: DetailData.value.title,
},
],
},
],
}),
},
],
});
</script>
... ... @@ -104,6 +189,7 @@ useHead({
:src="config.public.apiUrl + DetailData.image"
:alt="DetailData.title"
class="w-16 h-16 object-contain"
loading="lazy"
/>
<div>
<h1 class="text-2xl font-bold text-[#5961f9]">
... ...