在组件内部使用 React Router Link
Using react router Link inside components
我正在使用 Link 内部组件来访问不同的页面,例如
<Link to={'/documents/' + x.id}></Link
但是,这会导致 SEO 问题,因为页面更改时元标记不会刷新。我也在使用服务器端渲染。
使用 Link 的正确方法是什么仍然可以流畅地更改页面并仍然进行 SEO 优化。
谢谢
我个人使用在我的项目中创建一个 SEO 组件来避免出现问题。我也喜欢使用 react-helmet,它将管理对 <head/>
的所有更改
例如:
import Helmet from "react-helmet";
import React from "react";
// mini SEO component
function SEO ({ title, description, keywords, url, lang }) {
return (
<Helmet
htmlAttributes={{ lang }}
title={{ title }}
meta={[
{
name: 'description',
content: description
},
{
name: 'keywords',
content: keywords
},
{
property: 'og:url',
content: url
}
]}
/>
);
}
export default SEO;
因此,在每个页面中使用所需的道具导入它
<SEO
title='example'
description='example'
keywords=''
url='https://example.com'
lang='en-us'
/>
希望对您有所帮助。
谢谢@luiz-mariz,我已经在使用 react-helmet,但问题是我在 componentDidMount()
中获取页面信息,但是当我这样做时,爬虫没有读取信息因为他们不会等待 API 调用来传递有关内容的信息。那是我的错误。
我解决这个问题的方法是在加载页面之前获取特定页面信息(使用服务器端呈现),然后将该信息传递给 App 组件。
onPageLoad((sink) => {
const context = {};
const data = {
loading: true,
loggingIn: false,
document:-API CALL FOR DOCUMENT INFO-
};
const store = createStore(mainReducer, data, applyMiddleware(thunk));
const initialData = store.getState();
const stylesheet = new ServerStyleSheet();
const app = renderToString(stylesheet.collectStyles( // eslint-disable-line
<Provider store={store}>
<StaticRouter location={sink.request.url} context={context}>
<App />
</StaticRouter>
</Provider>));
const helmet = Helmet.renderStatic();
sink.appendToHead(helmet.meta.toString());
sink.appendToHead(helmet.title.toString());
sink.appendToHead(stylesheet.getStyleTags());
sink.renderIntoElementById('react-root', app);
sink.appendToBody(`
<script>
window.__PRELOADED_STATE__ = ${JSON.stringify(initialData).replace(/</g, '\u003c')}
</script>
`);
});
此外,我在 react-helmet 组件中添加了更多标签。可能对某些想要使用 facebook 或 twitter 共享功能的人有用。
const SEO = ({
schema, title, description, images, path, contentType, published, updated, category, tags, twitter,
}) => (
<Helmet>
<html lang="en" itemScope itemType={`http://schema.org/${schema}`} />
<title>{title}</title>
<meta name="description" content={description} />
<meta itemProp="name" content={title} />
<meta itemProp="description" content={description} />
<meta itemProp="image" content={(images && images.google)} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@sitename" />
<meta name="twitter:title" content={`${title} | Your-site-name`} />
<meta name="twitter:description" content={description} />
<meta name="twitter:creator" content={`@${twitter}` || '@sitename'} />
<meta name="twitter:image:src" content={(images && images.twitter)} />
<meta property="og:title" content={`${title} | Your-site-name`} />
<meta property="og:type" content={contentType} />
<meta property="og:url" content={url} />
<meta property="og:image" content={(images && images.facebook)} />
<meta property="og:description" content={description} />
<meta property="og:site_name" content="your-site-name" />
<meta name="fb:app_id" content="your-app-id" />
{published ? <meta name="article:published_time" content={published} /> : ''}
{updated ? <meta name="article:modified_time" content={updated} /> : ''}
{category ? <meta name="article:section" content={category} /> : ''}
{tags ? <meta name="article:tag" content={tags} /> : ''}
</Helmet>
);
我正在使用 Link 内部组件来访问不同的页面,例如
<Link to={'/documents/' + x.id}></Link
但是,这会导致 SEO 问题,因为页面更改时元标记不会刷新。我也在使用服务器端渲染。
使用 Link 的正确方法是什么仍然可以流畅地更改页面并仍然进行 SEO 优化。
谢谢
我个人使用在我的项目中创建一个 SEO 组件来避免出现问题。我也喜欢使用 react-helmet,它将管理对 <head/>
例如:
import Helmet from "react-helmet";
import React from "react";
// mini SEO component
function SEO ({ title, description, keywords, url, lang }) {
return (
<Helmet
htmlAttributes={{ lang }}
title={{ title }}
meta={[
{
name: 'description',
content: description
},
{
name: 'keywords',
content: keywords
},
{
property: 'og:url',
content: url
}
]}
/>
);
}
export default SEO;
因此,在每个页面中使用所需的道具导入它
<SEO
title='example'
description='example'
keywords=''
url='https://example.com'
lang='en-us'
/>
希望对您有所帮助。
谢谢@luiz-mariz,我已经在使用 react-helmet,但问题是我在 componentDidMount()
中获取页面信息,但是当我这样做时,爬虫没有读取信息因为他们不会等待 API 调用来传递有关内容的信息。那是我的错误。
我解决这个问题的方法是在加载页面之前获取特定页面信息(使用服务器端呈现),然后将该信息传递给 App 组件。
onPageLoad((sink) => {
const context = {};
const data = {
loading: true,
loggingIn: false,
document:-API CALL FOR DOCUMENT INFO-
};
const store = createStore(mainReducer, data, applyMiddleware(thunk));
const initialData = store.getState();
const stylesheet = new ServerStyleSheet();
const app = renderToString(stylesheet.collectStyles( // eslint-disable-line
<Provider store={store}>
<StaticRouter location={sink.request.url} context={context}>
<App />
</StaticRouter>
</Provider>));
const helmet = Helmet.renderStatic();
sink.appendToHead(helmet.meta.toString());
sink.appendToHead(helmet.title.toString());
sink.appendToHead(stylesheet.getStyleTags());
sink.renderIntoElementById('react-root', app);
sink.appendToBody(`
<script>
window.__PRELOADED_STATE__ = ${JSON.stringify(initialData).replace(/</g, '\u003c')}
</script>
`);
});
此外,我在 react-helmet 组件中添加了更多标签。可能对某些想要使用 facebook 或 twitter 共享功能的人有用。
const SEO = ({
schema, title, description, images, path, contentType, published, updated, category, tags, twitter,
}) => (
<Helmet>
<html lang="en" itemScope itemType={`http://schema.org/${schema}`} />
<title>{title}</title>
<meta name="description" content={description} />
<meta itemProp="name" content={title} />
<meta itemProp="description" content={description} />
<meta itemProp="image" content={(images && images.google)} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@sitename" />
<meta name="twitter:title" content={`${title} | Your-site-name`} />
<meta name="twitter:description" content={description} />
<meta name="twitter:creator" content={`@${twitter}` || '@sitename'} />
<meta name="twitter:image:src" content={(images && images.twitter)} />
<meta property="og:title" content={`${title} | Your-site-name`} />
<meta property="og:type" content={contentType} />
<meta property="og:url" content={url} />
<meta property="og:image" content={(images && images.facebook)} />
<meta property="og:description" content={description} />
<meta property="og:site_name" content="your-site-name" />
<meta name="fb:app_id" content="your-app-id" />
{published ? <meta name="article:published_time" content={published} /> : ''}
{updated ? <meta name="article:modified_time" content={updated} /> : ''}
{category ? <meta name="article:section" content={category} /> : ''}
{tags ? <meta name="article:tag" content={tags} /> : ''}
</Helmet>
);