在 React 应用中处理 SEO
最初发表在我的博客上
我已成功抵达巴厘岛,租了一辆摩托车,享受着从我住处到巴厘岛 Dojo 的旅程,我现在正在那里写这篇文章。
SEO定义
搜索引擎优化 (SEO) 是提高网站流量的质量和数量,提高网站或网页对网络搜索引擎用户的可见性的过程。
摘自维基百科
SPA 问题与 SEO 神话
所有使用 CRA(create-react-app)或 Gatsby 构建的用于提供动态内容的 React 应用都是单页应用,这意味着只有一个 index.html 文件来呈现应用的内容,也就是说,组件内的所有元标记都不会被搜索引擎抓取进行索引,而以前是这样的!自 2019 年 5 月起,谷歌宣布其爬虫现在可以像 Twitter/Facebook/Slack/Telegram 爬虫一样抓取 JavaScript 代码,所以当非技术人员提到这个 SPA SEO 误区时,一定要让他们明白。
在爬虫能够抓取 JavaScript 之前,我们所做的
大多数 React 开发人员使用 Next Js,因为它提供服务器端渲染,这意味着当用户访问某个 URL 时按需生成页面,或者使用一种称为预渲染的技术,这基本上是在构建时进行的服务器端渲染,Gatsby 仍然使用这种方法为你的静态内容生成页面,但不为动态内容提供该功能,不像 Netlify 等某些服务为你的动态内容提供预渲染。
SEO组件
受这个 GitHub 存储库(包含您需要在标题标签中包含的所有内容)的启发,我制作了这个 SEO 组件,我几乎在所有 Gatsby/React 应用程序中重复使用它来处理 SEO
我在代码中添加了一些注释来解释每个部分
import React from 'react'
import Helmet from 'react-helmet'
// This is the thumbnail that appears when someone shares your website
import Thumbnail from 'assets/me.jpg'
import {
url,
defaultTitle,
defaultDescription,
social,
socialLinks,
address,
contact,
legalName,
foundingDate,
logo,
author,
} from 'data/config'
export const SEO = ({
title,
type,
description,
articleBody,
datePublished,
dateModified,
cover,
location = '',
readTime,
}) => {
// This is Structured data that is recommended to have according to Google
// You can read more about it on Google's own documentation about structured data
// The first string is for the Article schema and the second one for the organization schema
const structuredDataArticle = `{
"@context": "http://schema.org",
"@type": "${type}",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://google.com/article"
},
"headline": "${description}",
"image": "${
cover ? `https://smakosh.com${cover}` : `https://smakosh.com${Thumbnail}`
}",
"datePublished": "${datePublished}",
"dateModified": "${dateModified}",
"author": {
"@type": "Person",
"name": "${author}"
},
"articleBody": "${articleBody}",
"publisher": {
"@type": "Organization",
"name": "${author}",
"logo": {
"@type": "ImageObject",
"url": "${logo}"
}
},
"description": "${description}",
"url": "${url}${location}/?ref=smakosh.com"
}`
const structuredDataOrganization = `{
"@context": "http://schema.org",
"@type": "${type}",
"legalName": "${legalName}",
"url": "${url}",
"logo": "${logo}",
"foundingDate": "${foundingDate}",
"founders": [{
"@type": "Person",
"name": "${legalName}"
}],
"contactPoint": [{
"@type": "ContactPoint",
"email": "${contact.email}",
"telephone": "${contact.phone}",
"contactType": "customer service"
}],
"address": {
"@type": "PostalAddress",
"addressLocality": "${address.city}",
"addressRegion": "${address.region}",
"addressCountry": "${address.country}",
"postalCode": "${address.zipCode}"
},
"sameAs": [
"${socialLinks.twitter}",
"${socialLinks.google}",
"${socialLinks.youtube}",
"${socialLinks.linkedin}",
"${socialLinks.instagram}",
"${socialLinks.github}"
]
}`
return (
// Notice I'm using react-helmet to inject these elements within the header tag
<Helmet>
{/* The description that appears under the title of your website appears on search engines results */}
<meta name="description" content={description || defaultDescription} />
{/* The thumbnail of your website */}
<meta
name="image"
content={cover ? `${url}${cover}` : `${url}${Thumbnail}`}
/>
{/* Opengraph meta tags for Facebook & LinkedIn */}
<meta property="og:url" content={`${url}${location}/?ref=smakosh.com`} />
<meta
property="og:type"
content={type === 'NewsArticle' ? 'NewsArticle' : 'website'}
/>
<meta
property="og:title"
content={title ? `Smakosh | ${title}` : defaultTitle}
/>
<meta
property="og:description"
content={description || defaultDescription}
/>
<meta
property="og:image"
content={cover ? `${url}${cover}` : `${url}${Thumbnail}`}
/>
{/* You can get this id when you create an app id on Facebook of your Facebook page */}
<meta property="fb:app_id" content={social.facebook} />
{/* These tags work for Twitter & Slack, notice I've included more custom tags like reading time etc... */}
<meta name="twitter:card" content="summary" />
<meta name="twitter:creator" content={socialLinks.twitter} />
<meta name="twitter:site" content={social.twitter} />
<meta
name="twitter:title"
content={title ? `Smakosh | ${title}` : defaultTitle}
/>
<meta
name="twitter:description"
content={description || defaultDescription}
/>
<meta
name="twitter:image:src"
content={cover ? `${url}${cover}` : `${url}${Thumbnail}`}
/>
{type === 'NewsArticle' && (
<meta name="twitter:label1" value="Reading time" />
)}
{type === 'NewsArticle' && (
<meta name="twitter:data1" value={`${readTime} min read`} />
)}
{type === 'NewsArticle' && (
<meta name="author" content="Ismail Ghallou" data-react-helmet="true" />
)}
{type === 'NewsArticle' && (
<meta
name="article:published_time"
content={datePublished}
data-react-helmet="true"
/>
)}
{/* Structured data */}
<script type="application/ld+json">
{type === 'NewsArticle'
? structuredDataArticle
: structuredDataOrganization}
</script>
{/* Not sure if this is still relevant as Google shut down their Google+ paltform */}
<link rel="publisher" href={socialLinks.google} />
{/* The title of your current page */}
<title>{title ? `Smakosh | ${title}` : defaultTitle}</title>
{/* Default language and direction */}
<html lang="en" dir="ltr" />
</Helmet>
)
}
我将其包含在每个组件中,使其像页面一样
import React from 'react'
import SEO from './SEO'
export default () => (
<div>
<SEO title="Home page" location="/" type="Organization" />
<h1>Home page</h1>
</div>
)
您可以从本博客的代码源中获取此组件。
提高网站在搜索结果中排名的技巧和工具
如果您的网站是像本网站这样的博客,强烈建议使用像这样的RSS 提要,因为某些应用程序和扩展程序会抓取提要并为您带来更多访问者,从而提高您在搜索结果中的排名。
拥有站点地图也有帮助,您必须将其提交到您的Google 搜索控制台。
您可以在此处测试您的结构化数据
请随意在评论部分提出您的问题,我会尽力回答所有问题。
文章来源:https://dev.to/smakosh/handling-seo-in-react-apps-32ae