seo-mask

Seo-mask is the use of search engine spider crawling principle (spider will only climb the content of the web page, will not care about the analysis of CSS and JS in the web page), make a special for SEO mirror site, I call it for SEO mask, let the spider see is more conducive to the site’s mask included. There is no need to change the source code of the original website. This method is suitable for THE SPA single-page application with dynamic data which has a large cost of SEO transformation.

Compare that to popular SEO solutions

advantages disadvantages
Prerender pre-rendered Easy to deploy and low development cost 1. Unable to render dynamic change of the page (e.g. a product details page); 2. Too many pages cause storage burden
SSR server rendering One step in place, the development of independent control page rendering 1. It costs too much to transform spa projects that have been operated online; 2. Seo specifications need to be considered in the development process; 3. Deep knowledge of the server is required to optimize rendering
seo-mask 1. No need to change the source code; 2. Be free to decide what needs to be crawled 1. Need to maintain a separate set of website code (very low development cost)

Scope of application

  • 3) Complex single page apps (forums, mall, news, etc.)
  • Has been operating online transformation server rendering costly single-page applications
  • Express as startup server (later versions will be released for different servers)

Demo

A simple blog site

The Demo site is a simple blog example developed based on CRA. In the example directory of the project, you can download it and run it locally:

git clone https://github.com/lipten/seo-mask.git

cd seo-mask/example

npm install

npm run start
Copy the code

Install

// With npm
npm install seo-mask

// With bower
bower install seo-mask
Copy the code

Usage

Make sure your project startup server is Express or Express-based Webpack-dev-server before doing the following.

  • In your startup server instancevar app = express()Add SEO-Mask middleware, and the corresponding configuration data.
app.use(require('seo-mask')({
  routes: require('.. /seo/routes'),
  tdk_config: require('.. /seo/tdk'),
  layout_render: require('.. /seo/src/layout'),}));Copy the code
  • If it is webpack-dev-server, it is in the devServer configurationbefore, add the code:

webpack: devServer.before

before(app, server) {
  app.use(require('seo-mask')({
    routes: require('.. /seo/routes'),
    tdk_config: require('.. /seo/tdk'),
    layout_render: require('.. /seo/src/layout'),})); . },Copy the code

Pass in an object containing routes, tdk_config, and layout_render.

SEO directory

Create a new SEO directory in your project that will be used to configure your mask site routing and TDK(title, description, and keywords) configuration for your site, as well as all the content of your mask site.

The directory structure is as follows:

├─ ├─ SRC /# mask website content| | - home /Build seO-mask pages according to your business needs| | | -- index. Ejs | | └ ─ ─ index. The js | | - blog /Make adjustments to the page of your site, in this case blog| | | -- index. Ejs | | └ ─ ─ index. The js | | - blog_detail / | | | -- index. Ejs | | └ ─ ─ index. The js | | -- layout. Ejs# SEo-mask site also needs a layout layout site head or some common elements| └ ─ ─ layout. Js# provide layout_render render for the entire mask website| - routes. JsThe routes configuration matches a specific path to the corresponding mask page└ ─ ─ TDK. JsConfigure the default TDK for a specific path, there must be a set of default TDKS for the site
Copy the code
  1. Edit tdk.js, routes.js and layout.js:
// seo/tdk.js // configure default TDK module.exports = {// default TDK, write at least one set'^ / $': {
    title: 'SEo-mask sample site',
    description: 'this is an seo - mask sample sites, project address https://github.com/lipten/seo-mask',
    keywords: 'seo,example'}, // Different TDKS can be matched according to different paths'^/blog$': {
    title: 'blog-SEo-mask example site',
  },
}

// seo/routes.js
module.exports = {
  '^/blog$': require('./src/blog'),
  '^/blog/\\d+$': require('./src/blog_detail'),
  '^ /? $': require('./src/home'),
}

// seo/src/layout.js

const ejs = require('ejs'NPM install -d ejs const fs = require('fs')
const path = require('path')
const template = fs.readFileSync(path.resolve(__dirname, './layout.ejs'), 'utf8');

const layout_render = (children) => {
  return ejs.render(template, children)
}
module.exports = layout_render

Copy the code
  1. Then define your layout.ejS template:
// seo/src/layout.ejs <! DOCTYPE html> <html> <head> <meta charset="utf-8">
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name= "renderer" content= "webkit" > <meta content="<%= tdk.keywords%>" name="keywords"/>
  <meta content="<%= tdk.description%>" name="description"/>
  <title><%= tdk.title%></title>
</head>
<body>
  <div id="root">
    <nav>
      <a href="/">home</a>
      <a href="/blog"> blog < / a > < / nav > < % - the result - % > < p > link < / p > < a href ="http://xxx.xx">xx</a>
  </div>
</body>
</html>

Copy the code
  1. Other page templates can be written in very concise HTML and rendered with JS:
Ejs <div> <h1> Seo-mask home </h1> <h2>Hello, world! </h2> <p> This is a simple blog site, you are now through the search engine spider access to see this simple site content, you can continue to visit the blog page to see my "blog". </p> <a href="/blog"</a> </div> // seo/ SRC /home/index.js const ejs = require('ejs')
const fs = require('fs')
const path = require('path')
const template = fs.readFileSync(path.resolve(__dirname, './index.ejs'), 'utf8');
const axios = require('axios');

module.exports = async (req) => {
  const result = ejs.render(template)
  return {result}
}
Copy the code
  1. Pages that need to pull dynamic data from the interface can also do this:
/ / seo/SRC/blog/index. The ejs < div > < ul > < % post_list. The blog list map ((item) = > {% > < li > < a href ="/blog/<%= item.id-%>" target="_blank"><%= item.title-%></a></li>
    <% })%>
  </ul>
</div>


// seo/src/blog/index.js
const ejs = require('ejs')
const fs = require('fs')
const path = require('path')
const template = fs.readFileSync(path.resolve(__dirname, './index.ejs'), 'utf8');
const axios = require('axios'); Module.exports = async (req) => {// pretend the blog data is pulled from the API. const res = await axios('/api/posts')
  const result = ejs.render(template, {post_list: res.data.items})
  return {result}
}

Copy the code
  1. You can also set the site title to the blog title in the blog details page:
/ / seo/SRC/blog_detail/index. The ejs < div > < h1 > blog title < % = post. The title % > < / h1 > < p > < % = post. The content % > < / p > < / div > / / seo/src/blog_detail/index.js const ejs = require('ejs')
const fs = require('fs')
const path = require('path')
const template = fs.readFileSync(path.resolve(__dirname, './index.ejs'), 'utf8');
const axios = require('axios');

module.exports = async (req) => {
  const post_id = req.path.split('/'[2] // Pretend that the blog data is pulled from the API. const res = await axios.get(`/api/post/${post_id}') const post = res.data const result = ejs.render(template, {post}) // Set the blog title to the website title const TDK = {title: '${post.title}- SEo-mask example website ', description: post.description, keywords:'SEO-Mask,blog'
  }
  return {result, tdk}
}

Copy the code

Resource

Single page application SPA to do SEO a unique solution

License

MIT