背景:公司的产品挂到了一个电商平台上,领导让我们给产品详情页做SEO,让用户在百度就能搜索到我们的产品, 但是商品详情是动态加载的,而且电商平台是第三方,他们肯定不会给我们做SEO,要实现SEO必须将商品页静态化, 只能想一些"歪门邪道"来做了;
[react component]
|
浏览器 - fake.com - nodejs - [shop server]
实现方式:浏览器通过服务域名(fake.com)请求到后端(由nodejs实现),后端先去三方调接口拿数据(从shop server获取数据), 然后去加载模板(由react实现,这一步可以直接读本地文件,也可以从某个服务器获取),把拿到的数据渲染到模板里,最后渲染到浏览器即可。
整个实现过程,我们只需要开发模板页和调用三方接口即可,只要把模板页按SEO标准设计好即可,但是最终搜索引擎收录和排名的情况,就是另外的手段了。
- client - 使用 `umi` 创建的项目,用来开发需要渲染的组件,按 `react + umi` 正常开发即可
- src/pages
- index.tsx - 一个简单的组件demo
- public - express项目的静态文件都在这里,我们放了工业云的首页和其他资源文件,express 如果不配置根目录的路由,默认会从资源目录下找 index.html
- services
- request.js - 单独封装的接口请求库,目前是扩展的`umi-request`
- app.js - `express` 入口文件
其他没提到的,不用去看
前端:开发组件
- react 17.x
- umi 3.x
- umi-request 1.4.0
后端:负责渲染
- express 4.x
- umi-request 1.4.0
运行 yarn start
- 首页:工业云的静态页面
- 产品页
访问 http://localhost:3000/product?ProductUuid=39049636-7997-4e77-89e8-8e9af57298ae
通过 express 实现
我们需要将前端代码编译生成的文件引入,尤其是 ./dist/umi.server
核心逻辑(app—demo.js):
const render = require('../client/dist/umi.server');
res.setHeader('Content-Type', 'text/html');
const {html, error, rootContainer} = await render({
// 有需要可带上 query
path: req.url,
context,
// 可自定义 html 模板
// htmlTemplate: defaultHtml,
// 启用流式渲染
// mode: 'stream',
// html 片段静态标记(适用于静态站点生成)
// staticMarkup: false,
// 扩展 getInitialProps 在服务端渲染中的参数
getInitialPropsCtx: data,
// manifest,正常情况下不需要
});
// support stream content
if (html instanceof Stream) {
html.pipe(res);
html.on('end', function () {
res.end();
});
} else {
res.send(html);
}
前端在 client 目录下进行开发,基本和正常的 react 组件一致
参考:client/src/pages/product/index_csr.tsx
前端也可以单独运行:yarn start
后端基于 express 实现
参考:routes/product/index.js
浏览器访问页面,然后右键 - 显示网页源代码,如果 <div id="root">...</div>
中有内容,说明成功