diff --git a/.eslintignore b/.eslintignore
index a3b85480f..b9a9017c5 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -2,4 +2,10 @@
 packages/docsify-server-renderer/build.js
 node_modules
 build
-server.js
\ No newline at end of file
+server.js
+cypress
+lib
+themes
+build
+docs/
+**/*.md
\ No newline at end of file
diff --git a/.eslintrc b/.eslintrc
deleted file mode 100644
index a8f7cd0c9..000000000
--- a/.eslintrc
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "extends": "xo-space/browser",
-  "rules": {
-    "semi": [2, "never"],
-    "no-return-assign": "off",
-    "no-unused-expressions": "off",
-    "no-new-func": "off",
-    "no-multi-assign": "off",
-    "no-mixed-operators": "off",
-    "max-params": "off",
-    "no-script-url": "off",
-    "camelcase": "off",
-    "no-warning-comments": "off"
-  },
-  "globals": {
-    "Docsify": true,
-    "$docsify": true,
-    "process": true
-  }
-}
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 000000000..087ae9e76
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,63 @@
+module.exports = {
+  root: true,
+  parser: 'babel-eslint',
+  parserOptions: {
+    sourceType: 'module',
+    ecmaVersion: 2019,
+  },
+  env: {
+    jest: true,
+    browser: true,
+    node: true,
+    es6: true,
+  },
+  plugins: ['prettier', 'import'],
+  extends: ['eslint:recommended', 'plugin:import/recommended'],
+  settings: {
+    'import/ignore': ['node_modules', '.json$'],
+  },
+  rules: {
+    'prettier/prettier': ['error'],
+    camelcase: ['warn'],
+    curly: ['error', 'all'],
+    'dot-notation': ['error'],
+    eqeqeq: ['error'],
+    'handle-callback-err': ['error'],
+    'new-cap': ['error'],
+    'no-alert': ['error'],
+    'no-caller': ['error'],
+    'no-eval': ['error'],
+    'no-labels': ['error'],
+    'no-lonely-if': ['error'],
+    'no-new': ['error'],
+    'no-proto': ['error'],
+    'no-return-assign': ['error'],
+    'no-self-compare': ['error'],
+    'no-shadow': ['warn'],
+    'no-shadow-restricted-names': ['error'],
+    'no-useless-call': ['error'],
+    'no-var': ['error'],
+    'no-void': ['error'],
+    'no-with': ['error'],
+    radix: ['error'],
+    'spaced-comment': ['error', 'always'],
+    strict: ['error', 'global'],
+    yoda: ['error', 'never'],
+
+    // Import rules
+    // Search way how integrate with `lerna`
+    'import/no-unresolved': 'off',
+    'import/imports-first': ['error'],
+    'import/newline-after-import': ['error'],
+    'import/no-duplicates': ['error'],
+    'import/no-mutable-exports': ['error'],
+    'import/no-named-as-default': ['error'],
+    'import/no-named-as-default-member': ['error'],
+    'import/order': ['warn'],
+  },
+  globals: {
+    Docsify: 'writable',
+    $docsify: 'writable',
+    dom: 'writable',
+  },
+};
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 000000000..3b2c8b180
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,20 @@
+# Number of days of inactivity before an issue becomes stale
+daysUntilStale: 60
+# Number of days of inactivity before a stale issue is closed
+daysUntilClose: 7
+# Issues with these labels will never be considered stale
+exemptLabels:
+  - pinned
+  - security
+  - On hold
+  - enhancement
+  - bug
+# Label to use when marking an issue as stale
+staleLabel: wontfix
+# Comment to post when marking an issue as stale. Set to `false` to disable
+markComment: >
+  This issue has been automatically marked as stale because it has not had
+  recent activity. It will be closed if no further activity occurs. Thank you
+  for your contributions.
+# Comment to post when closing a stale issue. Set to `false` to disable
+closeComment: false
diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
new file mode 100644
index 000000000..09fd229fa
--- /dev/null
+++ b/.github/workflows/e2e.yml
@@ -0,0 +1,31 @@
+name: Testing the e2e test suites
+
+on: 
+  push:
+   branches:
+    - master
+    - develop
+  pull_request:
+   branches:
+    - master
+    - develop
+
+jobs:
+  build:
+    runs-on: ubuntu-16.04
+    strategy:
+      matrix:
+        node-version: [10.x, 12.x, 13.x]
+
+    steps:
+    - uses: actions/checkout@v1
+    - name: Use Node.js ${{ matrix.node-version }}
+      uses: actions/setup-node@v1
+      with:
+        node-version: ${{ matrix.node-version }}
+    - name:  bootstrap
+      run: npm run bootstrap
+    - name: Build
+      run: npm run build
+    - name: end to end
+      run: npm run test:e2e
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 000000000..8e40422e8
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,31 @@
+name: Linting Checks
+
+on: 
+  push:
+   branches:
+    - master
+    - develop
+  pull_request:
+   branches:
+    - master
+    - develop
+
+jobs:
+  build:
+    runs-on: ubuntu-16.04
+    strategy:
+      matrix:
+        node-version: [10.x, 12.x, 13.x]
+
+    steps:
+    - uses: actions/checkout@v1
+    - name: Use Node.js ${{ matrix.node-version }}
+      uses: actions/setup-node@v1
+      with:
+        node-version: ${{ matrix.node-version }}
+    - name:  bootstrap
+      run: npm run bootstrap
+    - name: Build
+      run: npm run build
+    - name: Linting
+      run: npm run lint
diff --git a/.github/workflows/unit.yml b/.github/workflows/unit.yml
new file mode 100644
index 000000000..45c001f7a
--- /dev/null
+++ b/.github/workflows/unit.yml
@@ -0,0 +1,31 @@
+name: Unit tests Suite
+
+on: 
+  push:
+   branches:
+    - master
+    - develop
+  pull_request:
+   branches:
+    - master
+    - develop
+
+jobs:
+  build:
+    runs-on: ubuntu-16.04
+    strategy:
+      matrix:
+        node-version: [10.x, 12.x, 13.x]
+
+    steps:
+    - uses: actions/checkout@v1
+    - name: Use Node.js ${{ matrix.node-version }}
+      uses: actions/setup-node@v1
+      with:
+        node-version: ${{ matrix.node-version }}
+    - name:  bootstrap
+      run: npm run bootstrap
+    - name: Build
+      run: npm run build
+    - name: Unit tests
+      run: npm run test
diff --git a/.gitignore b/.gitignore
index ea4b5b805..e9803a96f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,8 @@
 node_modules
 themes/
 lib/
+cypress/integration/examples
+cypress/fixtures/docs
 
 # exceptions
 !.gitkeep
\ No newline at end of file
diff --git a/.prettierrc.js b/.prettierrc.js
new file mode 100644
index 000000000..a425d3f76
--- /dev/null
+++ b/.prettierrc.js
@@ -0,0 +1,4 @@
+module.exports = {
+  singleQuote: true,
+  trailingComma: 'es5',
+};
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 87576c5a3..000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-sudo: false
-language: node_js
-node_js: stable
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 9bf4d12b5..65a196532 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,4 +1,3 @@
 {
-  "editor.defaultFormatter": "esbenp.prettier-vscode",
-  "editor.formatOnSave": true
+  "editor.defaultFormatter": "esbenp.prettier-vscode"
 }
diff --git a/README.md b/README.md
index b8da0d8e5..e6fda5ba4 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 
   
-    
+    
   
 
 
@@ -10,8 +10,11 @@
 
 
   
-  
-  
+  
+    
 
+  
+  
+  
   
   
   
@@ -107,5 +110,3 @@ This project exists thanks to all the people who contribute. [[Contribute](CONTR
 ## License
 
 [MIT](LICENSE)
-
-[](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2Fdocsifyjs%2Fdocsify?ref=badge_large)
diff --git a/cypress.json b/cypress.json
new file mode 100644
index 000000000..60ed5aa53
--- /dev/null
+++ b/cypress.json
@@ -0,0 +1,3 @@
+{
+  "video": false
+}
diff --git a/cypress/fixtures/tpl/docs.index.html b/cypress/fixtures/tpl/docs.index.html
new file mode 100644
index 000000000..94d9526e1
--- /dev/null
+++ b/cypress/fixtures/tpl/docs.index.html
@@ -0,0 +1,123 @@
+
+
+  
+    
+    docsify-e2e-tests
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+  
+
+  
+    Loading Docsify e2e tests suite...
+    
+    
+    
+    
+    
+    
+    
+    
+
+    
+    
+  
+
diff --git a/cypress/integration/sidebar/config.spec.js b/cypress/integration/sidebar/config.spec.js
new file mode 100644
index 000000000..4c1b511a7
--- /dev/null
+++ b/cypress/integration/sidebar/config.spec.js
@@ -0,0 +1,344 @@
+context('sidebar.configurations', () => {
+  beforeEach(() => {
+    cy.visit('http://localhost:3000');
+  });
+
+  const quickStartIds = [
+    'initialize',
+    'writing-content',
+    'preview-your-site',
+    'manual-initialization',
+    'loading-dialog',
+  ];
+  quickStartIds.forEach(id => {
+    it('go to #quickstart?id=' + id, () => {
+      cy.get(
+        '.sidebar-nav > :nth-child(1) > :nth-child(1) > ul > :nth-child(1) > a'
+      ).click();
+
+      cy.get(`a.section-link[href='#/quickstart?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  const configurationIds = [
+    'el',
+    'repo',
+    'maxlevel',
+    'loadnavbar',
+    'loadsidebar',
+    'hidesidebar',
+    'submaxlevel',
+    'auto2top',
+    'homepage',
+    'basepath',
+    'relativepath',
+    'coverpage',
+    'logo',
+    'name',
+    'namelink',
+    'markdown',
+    'themecolor',
+    'alias',
+    'autoheader',
+    'executescript',
+    'noemoji',
+    'mergenavbar',
+    'formatupdated',
+    'externallinktarget',
+    'cornerexternallinktarget',
+    'externallinkrel',
+    'routermode',
+    'nocompilelinks',
+    'onlycover',
+    'requestheaders',
+    'ext',
+    'fallbacklanguages',
+    'notfoundpage',
+  ];
+  configurationIds.forEach(id => {
+    it('go to #configuration?id=' + id, () => {
+      cy.get('[href="#/configuration"]').click();
+
+      cy.get(`a.section-link[href='#/configuration?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500); // its more far from the cover
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  const morePagesIds = [
+    'sidebar',
+    'nested-sidebars',
+    'set-page-titles-from-sidebar-selection',
+    'table-of-contents',
+    'ignoring-subheaders',
+  ];
+  morePagesIds.forEach(id => {
+    it('go to #more-pages?id=' + id, () => {
+      cy.get('[href="#/more-pages"]').click();
+
+      cy.get(`a.section-link[href='#/more-pages?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  const customNavbarIds = [
+    'html',
+    'markdown',
+    'nesting',
+    'combining-custom-navbars-with-the-emoji-plugin',
+  ];
+  customNavbarIds.forEach(id => {
+    it('go to #custom-navbar?id=' + id, () => {
+      cy.get('[href="#/custom-navbar"]').click();
+
+      cy.get(`a.section-link[href='#/custom-navbar?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  const coverIds = [
+    'basic-usage',
+    'custom-background',
+    'coverpage-as-homepage',
+    'multiple-covers',
+  ];
+  coverIds.forEach(id => {
+    it('go to #cover?id=' + id, () => {
+      cy.get('[href="#/cover"]').click();
+
+      cy.get(`a.section-link[href='#/cover?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  const themesIds = ['other-themes'];
+  themesIds.forEach(id => {
+    it('go to #themes?id=' + id, () => {
+      cy.get('[href="#/themes"]').click();
+
+      cy.get(`a.section-link[href='#/themes?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  const pluginsIds = [
+    'full-text-search',
+    'google-analytics',
+    'emoji',
+    'external-script',
+    'zoom-image',
+    'edit-on-github',
+    'demo-code-with-instant-preview-and-jsfiddle-integration',
+    'copy-to-clipboard',
+    'disqus',
+    'gitalk',
+    'pagination',
+    'codefund',
+    'tabs',
+    'more-plugins',
+  ];
+  pluginsIds.forEach(id => {
+    it('go to #plugins?id=' + id, () => {
+      cy.get('[href="#/plugins"]').click();
+
+      cy.get(`a.section-link[href='#/plugins?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  const writeAPluginIds = ['full-configuration', 'example', 'tips'];
+  writeAPluginIds.forEach(id => {
+    it('go to #write-a-plugin?id=' + id, () => {
+      cy.get('[href="#/write-a-plugin"]').click();
+
+      cy.get(`a.section-link[href='#/write-a-plugin?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  const markdownIds = ['supports-mermaid'];
+  markdownIds.forEach(id => {
+    it('go to #markdown?id=' + id, () => {
+      cy.get('[href="#/markdown"]').click();
+
+      cy.get(`a.section-link[href='#/markdown?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  it('go to #Language-highlight', () => {
+    cy.get('a[href="#/language-highlight"]')
+      .click()
+      .then(() => {
+        cy.wait(500);
+        cy.matchImageSnapshot();
+      });
+  });
+
+  // const deployIds = [
+  //   'github-pages',
+  //   'gitlab-pages',
+  //   'firebase-hosting',
+  //   'vps',
+  //   'netlify',
+  //   'zeit-now',
+  //   'aws-amplify'
+  // ]
+  // deployIds.forEach(id => {
+  //   it('go to #deploy?id=' + id, () => {
+  //     cy.get('[href="#/deploy"]').click()
+
+  //     cy.get(`a.section-link[href='#/deploy?id=${id}']`)
+  //       .click()
+  //       .then(() => {
+  //         cy.wait(500)
+  //         cy.matchImageSnapshot()
+  //       })
+  //   })
+  // })
+
+  const helpersIds = [
+    'important-content',
+    'general-tips',
+    'ignore-to-compile-link',
+    'set-target-attribute-for-link',
+    'disable-link',
+    'github-task-lists',
+    'customise-id-for-headings',
+    'markdown-in-html-tag',
+  ];
+  helpersIds.forEach(id => {
+    it('go to #helpers?id=' + id, () => {
+      cy.get('[href="#/helpers"]').click();
+
+      cy.get(`a.section-link[href='#/helpers?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  const vueIds = ['basic-usage', 'combine-vuep-to-write-playground'];
+  vueIds.forEach(id => {
+    it('go to #vue?id=' + id, () => {
+      cy.get('[href="#/vue"]').click();
+
+      cy.get(`a.section-link[href='#/vue?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  const cdnIds = [
+    'latest-version',
+    'specific-version',
+    'compressed-file',
+    'other-cdn',
+  ];
+  cdnIds.forEach(id => {
+    it('go to #cdn?id=' + id, () => {
+      cy.get('[href="#/cdn"]').click();
+
+      cy.get(`a.section-link[href='#/cdn?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  const pwaIds = ['create-serviceworker', 'register', 'enjoy-it'];
+  pwaIds.forEach(id => {
+    it('go to #pwa?id=' + id, () => {
+      cy.get('[href="#/pwa"]').click();
+
+      cy.get(`a.section-link[href='#/pwa?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+
+  const ssrIds = [
+    'why-ssr',
+    'quick-start',
+    'custom-template',
+    'configuration',
+    'deploy-for-your-vps',
+  ];
+
+  ssrIds.forEach(id => {
+    it('go to #ssr?id=' + id, () => {
+      cy.get('[href="#/ssr"]').click();
+
+      cy.get(`a.section-link[href='#/ssr?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+  const embedFilesIds = [
+    'embedded-file-type',
+    'embedded-code-fragments',
+    'tag-attribute',
+    'the-code-block-highlight',
+  ];
+  embedFilesIds.forEach(id => {
+    it('go to #embed-files?id=' + id, () => {
+      cy.get('[href="#/embed-files"]').click();
+
+      cy.get(`a.section-link[href='#/embed-files?id=${id}']`)
+        .click()
+        .then(() => {
+          cy.wait(500);
+          cy.matchImageSnapshot();
+        });
+    });
+  });
+});
diff --git a/cypress/live.server.js b/cypress/live.server.js
new file mode 100644
index 000000000..bb22b8f07
--- /dev/null
+++ b/cypress/live.server.js
@@ -0,0 +1,13 @@
+const path = require('path')
+const LiveServer = require('live-server')
+
+const fixturePath = path.join(__dirname, './fixtures/docs')
+const args = process.argv.slice(2)
+console.log('[e2e tests] : args passed to live server', args)
+const params = {
+  port: args[0] || 3000,
+  root: args[1] || fixturePath,
+  open: false
+  // NoBrowser: true
+}
+LiveServer.start(params)
diff --git a/cypress/plugins/index.js b/cypress/plugins/index.js
new file mode 100644
index 000000000..aebcffbd7
--- /dev/null
+++ b/cypress/plugins/index.js
@@ -0,0 +1,18 @@
+// ***********************************************************
+// This example plugins/index.js can be used to load plugins
+//
+// You can change the location of this file or turn off loading
+// the plugins file with the 'pluginsFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/plugins-guide
+// ***********************************************************
+
+// This function is called when a project is opened or re-opened (e.g. due to
+// the project's config changing)
+const { addMatchImageSnapshotPlugin } = require('cypress-image-snapshot/plugin')
+module.exports = (on, config) => {
+  // `on` is used to hook into various events Cypress emits
+  // `config` is the resolved Cypress config
+  addMatchImageSnapshotPlugin(on, config)
+}
diff --git a/cypress/setup.js b/cypress/setup.js
new file mode 100644
index 000000000..6372ff347
--- /dev/null
+++ b/cypress/setup.js
@@ -0,0 +1,75 @@
+const copyDir = require('copy-dir')
+const path = require('path')
+const fs = require('fs')
+const { spawn } = require('child_process')
+
+const setup = async () => {
+  const PORT = process.env.PORT || 3000
+  global.__LIVESERVER__ = null
+  global.PORT = PORT
+
+  /**
+   * IN this test suite, we are going to test our docs site with all the css,js linked to our local build packages
+   *
+   *  1.1 Copy ../docs --> ./fixtures/docs
+   *  1.2 copy lib,themes --> ./fixtures/
+   *  2. change the content of fixtures/docs/index.html to use all the links from our local build
+   *  3. now jest runner will run to test all the *.spec.js files
+   *
+   */
+
+  const shippedDirs = ['lib', 'themes']
+
+  // 1
+  const docsPath = path.join(process.cwd(), './docs')
+  const fixtureDocsPath = path.join(__dirname, './fixtures/docs')
+
+  // 1.1
+  console.log('[cypress test docs] Copying the docs --> cypress/fixtures/docs')
+  copyDir.sync(docsPath, fixtureDocsPath)
+
+  // 1.2
+  shippedDirs.forEach(dir => {
+    const fromPath = path.join(process.cwd(), dir)
+    const toPath = path.join(__dirname, `./fixtures/docs/${dir}`)
+    console.log(
+      `[cypress test docs] Copying  ${dir} --> cypress/fixtures/docs/${dir}`
+    )
+    copyDir.sync(fromPath, toPath)
+  })
+
+  // 2
+  console.log(
+    '[cypress test docs] Replacing content the tpl/index.html --> cypress/fixtures/docs/index.html'
+  )
+  const indexHTMLtplPath = path.join(
+    __dirname,
+    './fixtures/tpl/docs.index.html'
+  )
+  const fixtureIndexPath = path.join(__dirname, './fixtures/docs/index.html')
+  const data = fs.readFileSync(indexHTMLtplPath, 'utf8')
+
+  // 3
+  const fixturePath = path.join(__dirname, './fixtures/docs')
+
+  fs.writeFileSync(fixtureIndexPath, data, 'utf8')
+  const child = spawn('node', [
+    path.join(__dirname, './live.server.js'),
+    PORT,
+    fixturePath
+  ])
+  child.on('exit', code => {
+    console.log(`Child process exited with code ${code}`)
+  })
+  child.stdout.on('data', data => {
+    console.log(`stdout: ${data}`)
+  })
+  child.stderr.on('data', data => {
+    console.log(`stderr: ${data}`)
+  })
+
+  // LiveServer.start(params)
+  global.__LIVESERVER__ = child
+}
+
+setup()
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #Language-highlight.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #Language-highlight.snap.png
new file mode 100644
index 000000000..c39f80f1a
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #Language-highlight.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #cdnid=compressed-file.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #cdnid=compressed-file.snap.png
new file mode 100644
index 000000000..fa2acf15f
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #cdnid=compressed-file.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #cdnid=latest-version.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #cdnid=latest-version.snap.png
new file mode 100644
index 000000000..1ef50abe8
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #cdnid=latest-version.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #cdnid=other-cdn.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #cdnid=other-cdn.snap.png
new file mode 100644
index 000000000..2193959a0
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #cdnid=other-cdn.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #cdnid=specific-version.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #cdnid=specific-version.snap.png
new file mode 100644
index 000000000..04e364cf3
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #cdnid=specific-version.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=alias.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=alias.snap.png
new file mode 100644
index 000000000..aaa0ed544
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=alias.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=auto2top.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=auto2top.snap.png
new file mode 100644
index 000000000..2ac6312cd
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=auto2top.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=autoheader.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=autoheader.snap.png
new file mode 100644
index 000000000..779f27af3
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=autoheader.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=basepath.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=basepath.snap.png
new file mode 100644
index 000000000..da2c844d8
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=basepath.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=cornerexternallinktarget.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=cornerexternallinktarget.snap.png
new file mode 100644
index 000000000..c41b09bbe
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=cornerexternallinktarget.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=coverpage.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=coverpage.snap.png
new file mode 100644
index 000000000..3c05b08b0
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=coverpage.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=el.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=el.snap.png
new file mode 100644
index 000000000..d9982b684
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=el.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=executescript.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=executescript.snap.png
new file mode 100644
index 000000000..48ca3772a
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=executescript.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=ext.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=ext.snap.png
new file mode 100644
index 000000000..21f3e0e01
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=ext.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=externallinkrel.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=externallinkrel.snap.png
new file mode 100644
index 000000000..52f1f0149
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=externallinkrel.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=externallinktarget.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=externallinktarget.snap.png
new file mode 100644
index 000000000..797a914b0
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=externallinktarget.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=fallbacklanguages.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=fallbacklanguages.snap.png
new file mode 100644
index 000000000..cdb789fcc
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=fallbacklanguages.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=formatupdated.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=formatupdated.snap.png
new file mode 100644
index 000000000..b8e49a654
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=formatupdated.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=hidesidebar.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=hidesidebar.snap.png
new file mode 100644
index 000000000..cbc01ef90
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=hidesidebar.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=homepage.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=homepage.snap.png
new file mode 100644
index 000000000..b2adecfc9
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=homepage.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=loadnavbar.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=loadnavbar.snap.png
new file mode 100644
index 000000000..71f703d11
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=loadnavbar.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=loadsidebar.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=loadsidebar.snap.png
new file mode 100644
index 000000000..50485725b
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=loadsidebar.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=logo.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=logo.snap.png
new file mode 100644
index 000000000..bae3433a7
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=logo.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=markdown.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=markdown.snap.png
new file mode 100644
index 000000000..4685abd7d
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=markdown.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=maxlevel.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=maxlevel.snap.png
new file mode 100644
index 000000000..9446381a7
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=maxlevel.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=mergenavbar.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=mergenavbar.snap.png
new file mode 100644
index 000000000..a34d06cd0
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=mergenavbar.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=name.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=name.snap.png
new file mode 100644
index 000000000..013977a49
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=name.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=namelink.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=namelink.snap.png
new file mode 100644
index 000000000..ae20a5ddb
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=namelink.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=nocompilelinks.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=nocompilelinks.snap.png
new file mode 100644
index 000000000..619704cbe
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=nocompilelinks.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=noemoji.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=noemoji.snap.png
new file mode 100644
index 000000000..321a77e2f
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=noemoji.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=notfoundpage.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=notfoundpage.snap.png
new file mode 100644
index 000000000..6ccfef833
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=notfoundpage.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=onlycover.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=onlycover.snap.png
new file mode 100644
index 000000000..3c5937436
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=onlycover.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=relativepath.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=relativepath.snap.png
new file mode 100644
index 000000000..16c7a96ab
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=relativepath.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=repo.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=repo.snap.png
new file mode 100644
index 000000000..8e5cd6c7d
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=repo.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=requestheaders.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=requestheaders.snap.png
new file mode 100644
index 000000000..eda49e1ec
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=requestheaders.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=routermode.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=routermode.snap.png
new file mode 100644
index 000000000..744b49515
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=routermode.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=submaxlevel.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=submaxlevel.snap.png
new file mode 100644
index 000000000..19bf00e35
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=submaxlevel.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=themecolor.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=themecolor.snap.png
new file mode 100644
index 000000000..0ae49f942
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #configurationid=themecolor.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #coverid=basic-usage.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #coverid=basic-usage.snap.png
new file mode 100644
index 000000000..debcf6e2c
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #coverid=basic-usage.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #coverid=coverpage-as-homepage.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #coverid=coverpage-as-homepage.snap.png
new file mode 100644
index 000000000..51751720f
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #coverid=coverpage-as-homepage.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #coverid=custom-background.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #coverid=custom-background.snap.png
new file mode 100644
index 000000000..17a306e13
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #coverid=custom-background.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #coverid=multiple-covers.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #coverid=multiple-covers.snap.png
new file mode 100644
index 000000000..354dd3b69
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #coverid=multiple-covers.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #custom-navbarid=combining-custom-navbars-with-the-emoji-plugin.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #custom-navbarid=combining-custom-navbars-with-the-emoji-plugin.snap.png
new file mode 100644
index 000000000..2fe604473
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #custom-navbarid=combining-custom-navbars-with-the-emoji-plugin.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #custom-navbarid=html.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #custom-navbarid=html.snap.png
new file mode 100644
index 000000000..87d117c52
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #custom-navbarid=html.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #custom-navbarid=markdown.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #custom-navbarid=markdown.snap.png
new file mode 100644
index 000000000..e31a5840f
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #custom-navbarid=markdown.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #custom-navbarid=nesting.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #custom-navbarid=nesting.snap.png
new file mode 100644
index 000000000..60effa6b9
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #custom-navbarid=nesting.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #embed-filesid=embedded-code-fragments.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #embed-filesid=embedded-code-fragments.snap.png
new file mode 100644
index 000000000..f8e05430c
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #embed-filesid=embedded-code-fragments.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #embed-filesid=embedded-file-type.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #embed-filesid=embedded-file-type.snap.png
new file mode 100644
index 000000000..702af8421
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #embed-filesid=embedded-file-type.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #embed-filesid=tag-attribute.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #embed-filesid=tag-attribute.snap.png
new file mode 100644
index 000000000..8b4ee81a1
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #embed-filesid=tag-attribute.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #embed-filesid=the-code-block-highlight.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #embed-filesid=the-code-block-highlight.snap.png
new file mode 100644
index 000000000..682642579
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #embed-filesid=the-code-block-highlight.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=customise-id-for-headings.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=customise-id-for-headings.snap.png
new file mode 100644
index 000000000..8f03a0760
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=customise-id-for-headings.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=disable-link.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=disable-link.snap.png
new file mode 100644
index 000000000..a6a717d33
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=disable-link.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=general-tips.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=general-tips.snap.png
new file mode 100644
index 000000000..3e0e3f178
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=general-tips.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=github-task-lists.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=github-task-lists.snap.png
new file mode 100644
index 000000000..02770c0ed
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=github-task-lists.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=ignore-to-compile-link.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=ignore-to-compile-link.snap.png
new file mode 100644
index 000000000..8e7074c26
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=ignore-to-compile-link.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=important-content.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=important-content.snap.png
new file mode 100644
index 000000000..d8ac2fa35
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=important-content.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=markdown-in-html-tag.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=markdown-in-html-tag.snap.png
new file mode 100644
index 000000000..842a27530
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=markdown-in-html-tag.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=set-target-attribute-for-link.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=set-target-attribute-for-link.snap.png
new file mode 100644
index 000000000..962347631
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #helpersid=set-target-attribute-for-link.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #markdownid=supports-mermaid.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #markdownid=supports-mermaid.snap.png
new file mode 100644
index 000000000..25a0244fe
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #markdownid=supports-mermaid.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=ignoring-subheaders.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=ignoring-subheaders.snap.png
new file mode 100644
index 000000000..d94e8ff6d
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=ignoring-subheaders.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=nested-sidebars.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=nested-sidebars.snap.png
new file mode 100644
index 000000000..726d86bf6
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=nested-sidebars.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=set-page-titles-from-sidebar-selection.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=set-page-titles-from-sidebar-selection.snap.png
new file mode 100644
index 000000000..aca69af3f
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=set-page-titles-from-sidebar-selection.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=sidebar.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=sidebar.snap.png
new file mode 100644
index 000000000..3e3ec1552
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=sidebar.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=table-of-contents.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=table-of-contents.snap.png
new file mode 100644
index 000000000..9d011dd48
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #more-pagesid=table-of-contents.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=codefund.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=codefund.snap.png
new file mode 100644
index 000000000..2e59a75b1
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=codefund.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=copy-to-clipboard.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=copy-to-clipboard.snap.png
new file mode 100644
index 000000000..4b16c2317
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=copy-to-clipboard.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=demo-code-with-instant-preview-and-jsfiddle-integration.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=demo-code-with-instant-preview-and-jsfiddle-integration.snap.png
new file mode 100644
index 000000000..6d38a0be9
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=demo-code-with-instant-preview-and-jsfiddle-integration.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=disqus.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=disqus.snap.png
new file mode 100644
index 000000000..a44c2de01
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=disqus.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=edit-on-github.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=edit-on-github.snap.png
new file mode 100644
index 000000000..d39fd6180
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=edit-on-github.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=emoji.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=emoji.snap.png
new file mode 100644
index 000000000..a7333e856
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=emoji.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=external-script.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=external-script.snap.png
new file mode 100644
index 000000000..c47986174
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=external-script.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=full-text-search.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=full-text-search.snap.png
new file mode 100644
index 000000000..7205b155e
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=full-text-search.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=gitalk.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=gitalk.snap.png
new file mode 100644
index 000000000..3b041be20
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=gitalk.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=google-analytics.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=google-analytics.snap.png
new file mode 100644
index 000000000..411faa937
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=google-analytics.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=more-plugins.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=more-plugins.snap.png
new file mode 100644
index 000000000..3ef52aa51
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=more-plugins.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=pagination.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=pagination.snap.png
new file mode 100644
index 000000000..4f007a4ca
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=pagination.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=tabs.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=tabs.snap.png
new file mode 100644
index 000000000..1bcb05baf
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=tabs.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=zoom-image.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=zoom-image.snap.png
new file mode 100644
index 000000000..e54fac3c8
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pluginsid=zoom-image.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pwaid=create-serviceworker.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pwaid=create-serviceworker.snap.png
new file mode 100644
index 000000000..b90a0e883
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pwaid=create-serviceworker.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pwaid=enjoy-it.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pwaid=enjoy-it.snap.png
new file mode 100644
index 000000000..72521e0e5
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pwaid=enjoy-it.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pwaid=register.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pwaid=register.snap.png
new file mode 100644
index 000000000..2ddcc370f
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #pwaid=register.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=initialize.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=initialize.snap.png
new file mode 100644
index 000000000..295545618
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=initialize.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=loading-dialog.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=loading-dialog.snap.png
new file mode 100644
index 000000000..0b770801f
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=loading-dialog.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=manual-initialization.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=manual-initialization.snap.png
new file mode 100644
index 000000000..8fd07268f
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=manual-initialization.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=preview-your-site.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=preview-your-site.snap.png
new file mode 100644
index 000000000..f455bc5c8
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=preview-your-site.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=writing-content.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=writing-content.snap.png
new file mode 100644
index 000000000..1c33262e1
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #quickstartid=writing-content.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=configuration.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=configuration.snap.png
new file mode 100644
index 000000000..0dde65b3c
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=configuration.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=custom-template.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=custom-template.snap.png
new file mode 100644
index 000000000..e47a8c8f8
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=custom-template.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=deploy-for-your-vps.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=deploy-for-your-vps.snap.png
new file mode 100644
index 000000000..1960a4f47
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=deploy-for-your-vps.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=quick-start.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=quick-start.snap.png
new file mode 100644
index 000000000..1cbcfa138
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=quick-start.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=why-ssr.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=why-ssr.snap.png
new file mode 100644
index 000000000..5a228ed17
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #ssrid=why-ssr.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #themesid=other-themes.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #themesid=other-themes.snap.png
new file mode 100644
index 000000000..2bf44b529
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #themesid=other-themes.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #vueid=basic-usage.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #vueid=basic-usage.snap.png
new file mode 100644
index 000000000..094800a70
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #vueid=basic-usage.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #vueid=combine-vuep-to-write-playground.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #vueid=combine-vuep-to-write-playground.snap.png
new file mode 100644
index 000000000..10bd8d6e9
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #vueid=combine-vuep-to-write-playground.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #write-a-pluginid=example.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #write-a-pluginid=example.snap.png
new file mode 100644
index 000000000..7408c6a19
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #write-a-pluginid=example.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #write-a-pluginid=full-configuration.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #write-a-pluginid=full-configuration.snap.png
new file mode 100644
index 000000000..75bd8bb57
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #write-a-pluginid=full-configuration.snap.png differ
diff --git a/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #write-a-pluginid=tips.snap.png b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #write-a-pluginid=tips.snap.png
new file mode 100644
index 000000000..889ee9d01
Binary files /dev/null and b/cypress/snapshots/sidebar/config.spec.js/sidebar.configurations -- go to #write-a-pluginid=tips.snap.png differ
diff --git a/cypress/support/commands.js b/cypress/support/commands.js
new file mode 100644
index 000000000..3e9454afa
--- /dev/null
+++ b/cypress/support/commands.js
@@ -0,0 +1,41 @@
+// ***********************************************
+// This example commands.js shows you how to
+// create various custom commands and overwrite
+// existing commands.
+//
+// For more comprehensive examples of custom
+// commands please read more here:
+// https://on.cypress.io/custom-commands
+// ***********************************************
+//
+//
+// -- This is a parent command --
+// Cypress.Commands.add("login", (email, password) => { ... })
+//
+//
+// -- This is a child command --
+// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
+//
+//
+// -- This is a dual command --
+// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
+//
+//
+// -- This will overwrite an existing command --
+// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
+
+import { addMatchImageSnapshotCommand } from 'cypress-image-snapshot/command'
+addMatchImageSnapshotCommand({
+  failureThreshold: 10.0,
+  failureThresholdType: 'percent',
+  customDiffConfig: { threshold: 10.0 },
+  capture: 'viewport',
+  timeout: '60000'
+})
+Cypress.Commands.add('setResolution', size => {
+  if (Cypress._.isArray(size)) {
+    cy.viewport(size[0], size[1])
+  } else {
+    cy.viewport(size)
+  }
+})
diff --git a/cypress/support/index.js b/cypress/support/index.js
new file mode 100644
index 000000000..d68db96df
--- /dev/null
+++ b/cypress/support/index.js
@@ -0,0 +1,20 @@
+// ***********************************************************
+// This example support/index.js is processed and
+// loaded automatically before your test files.
+//
+// This is a great place to put global configuration and
+// behavior that modifies Cypress.
+//
+// You can change the location of this file or turn off
+// automatically serving support files with the
+// 'supportFile' configuration option.
+//
+// You can read more here:
+// https://on.cypress.io/configuration
+// ***********************************************************
+
+// Import commands.js using ES2015 syntax:
+import './commands'
+
+// Alternatively you can use CommonJS syntax:
+// require('./commands')
diff --git a/docs/_media/example.js b/docs/_media/example.js
index 7b6f668cc..8cad2d730 100644
--- a/docs/_media/example.js
+++ b/docs/_media/example.js
@@ -5,12 +5,12 @@ const PORT = 8080
 
 /// [demo]
 const result = fetch(`${URL}:${PORT}`)
-  .then(function(response) {
-    return response.json();
+  .then(function (response) {
+    return response.json()
+  })
+  .then(function (myJson) {
+    console.log(JSON.stringify(myJson))
   })
-  .then(function(myJson) {
-    console.log(JSON.stringify(myJson));
-  });
 /// [demo]
 
 result.then(console.log).catch(console.error)
diff --git a/docs/cdn.md b/docs/cdn.md
index eba77a845..82b2d2d90 100644
--- a/docs/cdn.md
+++ b/docs/cdn.md
@@ -1,15 +1,15 @@
 # CDN
 
-Recommended: [unpkg](//unpkg.com), which will reflect the latest version as soon as it is published to npm. You can also browse the source of the npm package at [unpkg.com/docsify/](//unpkg.com/docsify/).
+Recommended: [jsDelivr](//cdn.jsdelivr.net), which will reflect the latest version as soon as it is published to npm. You can also browse the source of the npm package at [cdn.jsdelivr.net/npm/docsify/](//cdn.jsdelivr.net/npm/docsify/).
 
 ## Latest version
 
 ```html
 
-
+
 
 
-
+
 ```
 
 Alternatively, use [compressed files](#compressed-file).
@@ -18,28 +18,28 @@ Alternatively, use [compressed files](#compressed-file).
 
 ```html
 
-
+
 
 
-
+
 ```
 
 ## Compressed file
 
 ```html
 
-
+
 
 
-
+
 ```
 
 ```html
 
-
+
 
 
-
+
 ```
 
 ## Other CDN
diff --git a/docs/configuration.md b/docs/configuration.md
index bcbe2e0de..11797c794 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -7,8 +7,8 @@ You can configure the `window.$docsify`.
   window.$docsify = {
     repo: 'docsifyjs/docsify',
     maxLevel: 3,
-    coverpage: true
-  }
+    coverpage: true,
+  };
 
 ```
 
@@ -21,7 +21,7 @@ The DOM element to be mounted on initialization. It can be a CSS selector string
 
 ```js
 window.$docsify = {
-  el: '#app'
+  el: '#app',
 };
 ```
 
@@ -36,7 +36,7 @@ Configure the repository url or a string of `username/repo` can add the [GitHub
 window.$docsify = {
   repo: 'docsifyjs/docsify',
   // or
-  repo: 'https://github.com/docsifyjs/docsify/'
+  repo: 'https://github.com/docsifyjs/docsify/',
 };
 ```
 
@@ -49,7 +49,7 @@ Maximum Table of content level.
 
 ```js
 window.$docsify = {
-  maxLevel: 4
+  maxLevel: 4,
 };
 ```
 
@@ -66,7 +66,7 @@ window.$docsify = {
   loadNavbar: true,
 
   // load from nav.md
-  loadNavbar: 'nav.md'
+  loadNavbar: 'nav.md',
 };
 ```
 
@@ -83,7 +83,20 @@ window.$docsify = {
   loadSidebar: true,
 
   // load from summary.md
-  loadSidebar: 'summary.md'
+  loadSidebar: 'summary.md',
+};
+```
+
+## hideSidebar
+
+- Type : `Boolean`
+- Default: `true`
+
+This option will completely hide your sidebar and wont render any content of the side even .
+
+```js
+window.$docsify = {
+  hideSidebar: true,
 };
 ```
 
@@ -96,7 +109,7 @@ Add table of contents (TOC) in custom sidebar.
 
 ```js
 window.$docsify = {
-  subMaxLevel: 2
+  subMaxLevel: 2,
 };
 ```
 
@@ -109,7 +122,7 @@ Scrolls to the top of the screen when the route is changed.
 
 ```js
 window.$docsify = {
-  auto2top: true
+  auto2top: true,
 };
 ```
 
@@ -127,7 +140,7 @@ window.$docsify = {
 
   // Or use the readme in your repo
   homepage:
-    'https://raw.githubusercontent.com/docsifyjs/docsify/master/README.md'
+    'https://raw.githubusercontent.com/docsifyjs/docsify/master/README.md',
 };
 ```
 
@@ -146,7 +159,7 @@ window.$docsify = {
 
   // Even can load files from other repo
   basePath:
-    'https://raw.githubusercontent.com/ryanmcdermott/clean-code-javascript/master/'
+    'https://raw.githubusercontent.com/ryanmcdermott/clean-code-javascript/master/',
 };
 ```
 
@@ -186,7 +199,7 @@ window.$docsify = {
   relativePath: true,
 
   // Relative path disabled (default value)
-  relativePath: false
+  relativePath: false,
 };
 ```
 
@@ -210,8 +223,8 @@ window.$docsify = {
   // mutiple covers and custom file name
   coverpage: {
     '/': 'cover.md',
-    '/zh-cn/': 'cover.md'
-  }
+    '/zh-cn/': 'cover.md',
+  },
 };
 ```
 
@@ -223,7 +236,7 @@ Website logo as it appears in the sidebar, you can resize by CSS.
 
 ```js
 window.$docsify = {
-  logo: '/_media/icon.svg'
+  logo: '/_media/icon.svg',
 };
 ```
 
@@ -235,7 +248,15 @@ Website name as it appears in the sidebar.
 
 ```js
 window.$docsify = {
-  name: 'docsify'
+  name: 'docsify',
+};
+```
+
+The name field can also contain custom HTML for easier customization:
+
+```js
+window.$docsify = {
+  name: 'docsify',
 };
 ```
 
@@ -253,8 +274,8 @@ window.$docsify = {
   // For each route
   nameLink: {
     '/zh-cn/': '/zh-cn/',
-    '/': '/'
-  }
+    '/': '/',
+  },
 };
 ```
 
@@ -272,15 +293,15 @@ window.$docsify = {
     renderer: {
       link: function() {
         // ...
-      }
-    }
+      },
+    },
   },
 
   // function
   markdown: function(marked, renderer) {
     // ...
     return marked;
-  }
+  },
 };
 ```
 
@@ -292,7 +313,7 @@ Customize the theme color. Use [CSS3 variables](https://developer.mozilla.org/en
 
 ```js
 window.$docsify = {
-  themeColor: '#3F51B5'
+  themeColor: '#3F51B5',
 };
 ```
 
@@ -309,8 +330,8 @@ window.$docsify = {
     '/zh-cn/changelog': '/changelog',
     '/changelog':
       'https://raw.githubusercontent.com/docsifyjs/docsify/master/CHANGELOG',
-    '/.*/_sidebar.md': '/_sidebar.md' // See #301
-  }
+    '/.*/_sidebar.md': '/_sidebar.md', // See #301
+  },
 };
 ```
 
@@ -323,7 +344,7 @@ If `loadSidebar` and `autoHeader` are both enabled, for each link in `_sidebar.m
 ```js
 window.$docsify = {
   loadSidebar: true,
-  autoHeader: true
+  autoHeader: true,
 };
 ```
 
@@ -335,7 +356,7 @@ Execute the script on the page. Only parse the first script tag([demo](themes)).
 
 ```js
 window.$docsify = {
-  executeScript: true
+  executeScript: true,
 };
 ```
 
@@ -357,10 +378,12 @@ Disabled emoji parse.
 
 ```js
 window.$docsify = {
-  noEmoji: true
+  noEmoji: true,
 };
 ```
 
+?> If this options is `false` but you dont want to emojify some specific colons , [Refer this](https://github.com/docsifyjs/docsify/issues/742#issuecomment-586313143)
+
 ## mergeNavbar
 
 - type: `Boolean`
@@ -369,7 +392,7 @@ Navbar will be merged with the sidebar on smaller screens.
 
 ```js
 window.$docsify = {
-  mergeNavbar: true
+  mergeNavbar: true,
 };
 ```
 
@@ -388,7 +411,7 @@ window.$docsify = {
     // ...
 
     return time;
-  }
+  },
 };
 ```
 
@@ -401,7 +424,7 @@ Target to open external links inside the markdown. Default `'_blank'` (new windo
 
 ```js
 window.$docsify = {
-  externalLinkTarget: '_self' // default: '_blank'
+  externalLinkTarget: '_self', // default: '_blank'
 };
 ```
 
@@ -414,7 +437,7 @@ Target to open external link at the top right corner. Default `'_blank'` (new wi
 
 ```js
 window.$docsify = {
-  cornerExternalLinkTarget: '_self' // default: '_blank'
+  cornerExternalLinkTarget: '_self', // default: '_blank'
 };
 ```
 
@@ -427,7 +450,7 @@ Default `'noopener'` (no opener) prevents the newly opened external page (when [
 
 ```js
 window.$docsify = {
-  externalLinkTarget: '' // default: 'noopener'
+  externalLinkTarget: '', // default: 'noopener'
 };
 ```
 
@@ -438,7 +461,7 @@ window.$docsify = {
 
 ```js
 window.$docsify = {
-  routerMode: 'history' // default: 'hash'
+  routerMode: 'history', // default: 'hash'
 };
 ```
 
@@ -450,7 +473,7 @@ Sometimes we do not want docsify to handle our links. See [#203](https://github.
 
 ```js
 window.$docsify = {
-  noCompileLinks: ['/foo', '/bar/.*']
+  noCompileLinks: ['/foo', '/bar/.*'],
 };
 ```
 
@@ -462,7 +485,7 @@ Only coverpage is loaded when visiting the home page.
 
 ```js
 window.$docsify = {
-  onlyCover: false
+  onlyCover: false,
 };
 ```
 
@@ -475,8 +498,18 @@ Set the request resource headers.
 ```js
 window.$docsify = {
   requestHeaders: {
-    'x-token': 'xxx'
-  }
+    'x-token': 'xxx',
+  },
+};
+```
+
+Such as setting the cache
+
+```js
+window.$docsify = {
+  requestHeaders: {
+    'cache-control': 'max-age=600',
+  },
 };
 ```
 
@@ -488,7 +521,7 @@ Request file extension.
 
 ```js
 window.$docsify = {
-  ext: '.md'
+  ext: '.md',
 };
 ```
 
@@ -506,7 +539,7 @@ Example:
 
 ```js
 window.$docsify = {
-  fallbackLanguages: ['fr', 'de']
+  fallbackLanguages: ['fr', 'de'],
 };
 ```
 
@@ -518,7 +551,7 @@ Load the `_404.md` file:
 
 ```js
 window.$docsify = {
-  notFoundPage: true
+  notFoundPage: true,
 };
 ```
 
@@ -526,7 +559,7 @@ Load the customised path of the 404 page:
 
 ```js
 window.$docsify = {
-  notFoundPage: 'my404.md'
+  notFoundPage: 'my404.md',
 };
 ```
 
@@ -536,9 +569,22 @@ Load the right 404 page according to the localisation:
 window.$docsify = {
   notFoundPage: {
     '/': '_404.md',
-    '/de': 'de/_404.md'
-  }
+    '/de': 'de/_404.md',
+  },
 };
 ```
 
 > Note: The options with fallbackLanguages didn't work with the `notFoundPage` options.
+
+## topMargin
+
+- type: `Number`
+- default: `0`
+
+Adds a space on top when scrolling content page to reach the selected section. This is useful in case you have a _sticky-header_ layout and you want to align anchors to the end of your header.
+
+```js
+window.$docsify = {
+  topMargin: 90, // default: 0
+};
+```
\ No newline at end of file
diff --git a/docs/cover.md b/docs/cover.md
index 555f4ff7a..878747a7e 100644
--- a/docs/cover.md
+++ b/docs/cover.md
@@ -14,7 +14,7 @@ Set `coverpage` to **true**, and create a `_coverpage.md`:
     coverpage: true
   }
 
-
+
 ```
 
 ```markdown
diff --git a/docs/custom-navbar.md b/docs/custom-navbar.md
index 324ad8104..14b6c8b3b 100644
--- a/docs/custom-navbar.md
+++ b/docs/custom-navbar.md
@@ -30,7 +30,7 @@ Alternatively, you can create a custom markdown-based navigation file by setting
     loadNavbar: true
   }
 
-
+
 ```
 
 ```markdown
@@ -82,8 +82,8 @@ If you use the [emoji plugin](plugins#emoji):
     // ...
   }
 
-
-
+
+
 ```
 
 you could, for example, use flag emojis in your custom navbar Markdown file:
diff --git a/docs/deploy.md b/docs/deploy.md
index 6bfe90445..d68b5c9dc 100644
--- a/docs/deploy.md
+++ b/docs/deploy.md
@@ -128,9 +128,10 @@ frontend:
 
 ```
 
-6. Add the following Redirect rules in their displayed order.
+6. Add the following Redirect rules in their displayed order. Note that the second record is a PNG image where you can change it with any image format you are using. 
 
 | Source address | Target address | Type          |
 |----------------|----------------|---------------|
 | /<*>.md        | /<*>.md        | 200 (Rewrite) |
+| /<*>.png       | /<*>.png       | 200 (Rewrite) |
 | /<*>           | /index.html    | 200 (Rewrite) |        
diff --git a/docs/helpers.md b/docs/helpers.md
index b047d3673..83c59784a 100644
--- a/docs/helpers.md
+++ b/docs/helpers.md
@@ -2,6 +2,8 @@
 
 docsify extends Markdown syntax to make your documents more readable.
 
+> Note:  For the special code syntax cases, you'd better put them within a code backticks to avoid any conflicting from configurations or emojis. 
+
 ## important content
 
 Important content like:
@@ -81,9 +83,12 @@ You will get `link`html. Do not worry, you can still set ti
   - [ ] bim
   - [ ] lim
 
-## Image resizing
+## Image
+
+### Resizing
 
 ```md
+
 
 
 
@@ -96,6 +101,18 @@ You will get `link`html. Do not worry, you can still set ti
 
 
 
+### Customise class
+
+```md
+
+```
+
+### Customise ID
+
+```md
+
+```
+
 ## Customise ID for headings
 
 ```md
diff --git a/docs/index.html b/docs/index.html
index 6d0e008b2..39c32b814 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -10,11 +10,13 @@
   
   
   
-  
-  
-  
-  
-  
+  
+  
+  
+  
+ 
+  
+  
   `
+  return ``;
 }
diff --git a/src/core/router/history/abstract.js b/src/core/router/history/abstract.js
index 2c0bd951d..02881f165 100644
--- a/src/core/router/history/abstract.js
+++ b/src/core/router/history/abstract.js
@@ -1,25 +1,25 @@
-import {History} from './base'
-import {parseQuery} from '../util'
+import { parseQuery } from '../util';
+import { History } from './base';
 
 export class AbstractHistory extends History {
   constructor(config) {
-    super(config)
-    this.mode = 'abstract'
+    super(config);
+    this.mode = 'abstract';
   }
 
   parse(path) {
-    let query = ''
+    let query = '';
 
-    const queryIndex = path.indexOf('?')
+    const queryIndex = path.indexOf('?');
     if (queryIndex >= 0) {
-      query = path.slice(queryIndex + 1)
-      path = path.slice(0, queryIndex)
+      query = path.slice(queryIndex + 1);
+      path = path.slice(0, queryIndex);
     }
 
     return {
       path,
       file: this.getFile(path),
-      query: parseQuery(query)
-    }
+      query: parseQuery(query),
+    };
   }
 }
diff --git a/src/core/router/history/base.js b/src/core/router/history/base.js
index 7ea763d8d..68c98b7f5 100644
--- a/src/core/router/history/base.js
+++ b/src/core/router/history/base.js
@@ -4,57 +4,59 @@ import {
   stringifyQuery,
   cleanPath,
   replaceSlug,
-  resolvePath
-} from '../util'
-import {noop, merge} from '../../util/core'
+  resolvePath,
+} from '../util';
+import { noop, merge } from '../../util/core';
 
-const cached = {}
+const cached = {};
 
 function getAlias(path, alias, last) {
   const match = Object.keys(alias).filter(key => {
-    const re = cached[key] || (cached[key] = new RegExp(`^${key}$`))
-    return re.test(path) && path !== last
-  })[0]
+    const re = cached[key] || (cached[key] = new RegExp(`^${key}$`));
+    return re.test(path) && path !== last;
+  })[0];
 
-  return match ?
-    getAlias(path.replace(cached[match], alias[match]), alias, path) :
-    path
+  return match
+    ? getAlias(path.replace(cached[match], alias[match]), alias, path)
+    : path;
 }
 
 function getFileName(path, ext) {
-  return new RegExp(`\\.(${ext.replace(/^\./, '')}|html)$`, 'g').test(path) ?
-    path :
-    /\/$/g.test(path) ? `${path}README${ext}` : `${path}${ext}`
+  return new RegExp(`\\.(${ext.replace(/^\./, '')}|html)$`, 'g').test(path)
+    ? path
+    : /\/$/g.test(path)
+    ? `${path}README${ext}`
+    : `${path}${ext}`;
 }
 
 export class History {
   constructor(config) {
-    this.config = config
+    this.config = config;
   }
 
   getBasePath() {
-    return this.config.basePath
+    return this.config.basePath;
   }
 
   getFile(path = this.getCurrentPath(), isRelative) {
-    const {config} = this
-    const base = this.getBasePath()
-    const ext = typeof config.ext === 'string' ? config.ext : '.md'
+    const { config } = this;
+    const base = this.getBasePath();
+    const ext = typeof config.ext === 'string' ? config.ext : '.md';
 
-    path = config.alias ? getAlias(path, config.alias) : path
-    path = getFileName(path, ext)
-    path = path === `/README${ext}` ? config.homepage || path : path
-    path = isAbsolutePath(path) ? path : getPath(base, path)
+    path = config.alias ? getAlias(path, config.alias) : path;
+    path = getFileName(path, ext);
+    path = path === `/README${ext}` ? config.homepage || path : path;
+    path = isAbsolutePath(path) ? path : getPath(base, path);
 
     if (isRelative) {
-      path = path.replace(new RegExp(`^${base}`), '')
+      path = path.replace(new RegExp(`^${base}`), '');
     }
 
-    return path
+    return path;
   }
 
   onchange(cb = noop) {
-    cb()
+    cb();
   }
 
   getCurrentPath() {}
@@ -64,23 +66,28 @@ export class History {
   parse() {}
 
   toURL(path, params, currentRoute) {
-    const local = currentRoute && path[0] === '#'
-    const route = this.parse(replaceSlug(path))
+    const local = currentRoute && path[0] === '#';
+    const route = this.parse(replaceSlug(path));
 
-    route.query = merge({}, route.query, params)
-    path = route.path + stringifyQuery(route.query)
-    path = path.replace(/\.md(\?)|\.md$/, '$1')
+    route.query = merge({}, route.query, params);
+    path = route.path + stringifyQuery(route.query);
+    path = path.replace(/\.md(\?)|\.md$/, '$1');
 
     if (local) {
-      const idIndex = currentRoute.indexOf('?')
+      const idIndex = currentRoute.indexOf('?');
       path =
-        (idIndex > 0 ? currentRoute.substring(0, idIndex) : currentRoute) + path
+        (idIndex > 0 ? currentRoute.substring(0, idIndex) : currentRoute) +
+        path;
     }
 
     if (this.config.relativePath && path.indexOf('/') !== 0) {
-      const currentDir = currentRoute.substring(0, currentRoute.lastIndexOf('/') + 1)
-      return cleanPath(resolvePath(currentDir + path))
+      const currentDir = currentRoute.substring(
+        0,
+        currentRoute.lastIndexOf('/') + 1
+      );
+      return cleanPath(resolvePath(currentDir + path));
     }
-    return cleanPath('/' + path)
+
+    return cleanPath('/' + path);
   }
 }
diff --git a/src/core/router/history/hash.js b/src/core/router/history/hash.js
index 2674d5d0d..166af9ab5 100644
--- a/src/core/router/history/hash.js
+++ b/src/core/router/history/hash.js
@@ -1,76 +1,95 @@
-import {History} from './base'
-import {noop} from '../../util/core'
-import {on} from '../../util/dom'
-import {parseQuery, cleanPath, replaceSlug} from '../util'
+import { noop } from '../../util/core';
+import { on } from '../../util/dom';
+import { parseQuery, cleanPath, replaceSlug } from '../util';
+import { History } from './base';
 
 function replaceHash(path) {
-  const i = location.href.indexOf('#')
-  location.replace(location.href.slice(0, i >= 0 ? i : 0) + '#' + path)
+  const i = location.href.indexOf('#');
+  location.replace(location.href.slice(0, i >= 0 ? i : 0) + '#' + path);
 }
 
 export class HashHistory extends History {
   constructor(config) {
-    super(config)
-    this.mode = 'hash'
+    super(config);
+    this.mode = 'hash';
   }
 
   getBasePath() {
-    const path = window.location.pathname || ''
-    const base = this.config.basePath
+    const path = window.location.pathname || '';
+    const base = this.config.basePath;
 
-    return /^(\/|https?:)/g.test(base) ? base : cleanPath(path + '/' + base)
+    return /^(\/|https?:)/g.test(base) ? base : cleanPath(path + '/' + base);
   }
 
   getCurrentPath() {
     // We can't use location.hash here because it's not
     // consistent across browsers - Firefox will pre-decode it!
-    const href = location.href
-    const index = href.indexOf('#')
-    return index === -1 ? '' : href.slice(index + 1)
+    const href = location.href;
+    const index = href.indexOf('#');
+    return index === -1 ? '' : href.slice(index + 1);
   }
 
   onchange(cb = noop) {
-    on('hashchange', cb)
+    // The hashchange event does not tell us if it originated from
+    // a clicked link or by moving back/forward in the history;
+    // therefore we set a `navigating` flag when a link is clicked
+    // to be able to tell these two scenarios apart
+    let navigating = false;
+
+    on('click', e => {
+      const el = e.target.tagName === 'A' ? e.target : e.target.parentNode;
+
+      if (el.tagName === 'A' && !/_blank/.test(el.target)) {
+        navigating = true;
+      }
+    });
+
+    on('hashchange', e => {
+      const source = navigating ? 'navigate' : 'history';
+      navigating = false;
+      cb({ event: e, source });
+    });
   }
 
   normalize() {
-    let path = this.getCurrentPath()
+    let path = this.getCurrentPath();
 
-    path = replaceSlug(path)
+    path = replaceSlug(path);
 
     if (path.charAt(0) === '/') {
-      return replaceHash(path)
+      return replaceHash(path);
     }
-    replaceHash('/' + path)
+
+    replaceHash('/' + path);
   }
 
   /**
    * Parse the url
-   * @param {string} [path=location.herf]
+   * @param {string} [path=location.herf] URL to be parsed
    * @return {object} { path, query }
    */
   parse(path = location.href) {
-    let query = ''
+    let query = '';
 
-    const hashIndex = path.indexOf('#')
+    const hashIndex = path.indexOf('#');
     if (hashIndex >= 0) {
-      path = path.slice(hashIndex + 1)
+      path = path.slice(hashIndex + 1);
     }
 
-    const queryIndex = path.indexOf('?')
+    const queryIndex = path.indexOf('?');
     if (queryIndex >= 0) {
-      query = path.slice(queryIndex + 1)
-      path = path.slice(0, queryIndex)
+      query = path.slice(queryIndex + 1);
+      path = path.slice(0, queryIndex);
     }
 
     return {
       path,
       file: this.getFile(path, true),
-      query: parseQuery(query)
-    }
+      query: parseQuery(query),
+    };
   }
 
   toURL(path, params, currentRoute) {
-    return '#' + super.toURL(path, params, currentRoute)
+    return '#' + super.toURL(path, params, currentRoute);
   }
 }
diff --git a/src/core/router/history/html5.js b/src/core/router/history/html5.js
index 04c53919b..d0b2a9a31 100644
--- a/src/core/router/history/html5.js
+++ b/src/core/router/history/html5.js
@@ -1,65 +1,67 @@
-import {History} from './base'
-import {noop} from '../../util/core'
-import {on} from '../../util/dom'
-import {parseQuery, getPath} from '../util'
+import { noop } from '../../util/core';
+import { on } from '../../util/dom';
+import { parseQuery, getPath } from '../util';
+import { History } from './base';
 
 export class HTML5History extends History {
   constructor(config) {
-    super(config)
-    this.mode = 'history'
+    super(config);
+    this.mode = 'history';
   }
 
   getCurrentPath() {
-    const base = this.getBasePath()
-    let path = window.location.pathname
+    const base = this.getBasePath();
+    let path = window.location.pathname;
 
     if (base && path.indexOf(base) === 0) {
-      path = path.slice(base.length)
+      path = path.slice(base.length);
     }
 
-    return (path || '/') + window.location.search + window.location.hash
+    return (path || '/') + window.location.search + window.location.hash;
   }
 
   onchange(cb = noop) {
     on('click', e => {
-      const el = e.target.tagName === 'A' ? e.target : e.target.parentNode
+      const el = e.target.tagName === 'A' ? e.target : e.target.parentNode;
 
       if (el.tagName === 'A' && !/_blank/.test(el.target)) {
-        e.preventDefault()
-        const url = el.href
-        window.history.pushState({key: url}, '', url)
-        cb()
+        e.preventDefault();
+        const url = el.href;
+        window.history.pushState({ key: url }, '', url);
+        cb({ event: e, source: 'navigate' });
       }
-    })
+    });
 
-    on('popstate', cb)
+    on('popstate', e => {
+      cb({ event: e, source: 'history' });
+    });
   }
 
   /**
    * Parse the url
-   * @param {string} [path=location.href]
+   * @param {string} [path=location.href] URL to be parsed
    * @return {object} { path, query }
    */
   parse(path = location.href) {
-    let query = ''
+    let query = '';
 
-    const queryIndex = path.indexOf('?')
+    const queryIndex = path.indexOf('?');
     if (queryIndex >= 0) {
-      query = path.slice(queryIndex + 1)
-      path = path.slice(0, queryIndex)
+      query = path.slice(queryIndex + 1);
+      path = path.slice(0, queryIndex);
     }
 
-    const base = getPath(location.origin)
-    const baseIndex = path.indexOf(base)
+    const base = getPath(location.origin);
+    const baseIndex = path.indexOf(base);
 
     if (baseIndex > -1) {
-      path = path.slice(baseIndex + base.length)
+      path = path.slice(baseIndex + base.length);
     }
 
     return {
       path,
       file: this.getFile(path),
-      query: parseQuery(query)
-    }
+      query: parseQuery(query),
+    };
   }
 }
diff --git a/src/core/router/index.js b/src/core/router/index.js
index 943fe6c3e..1cb2f67d8 100644
--- a/src/core/router/index.js
+++ b/src/core/router/index.js
@@ -1,45 +1,47 @@
-import {HashHistory} from './history/hash'
-import {HTML5History} from './history/html5'
-import {supportsPushState} from '../util/env'
-import * as dom from '../util/dom'
+import { supportsPushState } from '../util/env';
+import * as dom from '../util/dom';
+import { HashHistory } from './history/hash';
+import { HTML5History } from './history/html5';
+import { noop } from '../util/core';
 
 export function routerMixin(proto) {
-  proto.route = {}
+  proto.route = {};
 }
 
-let lastRoute = {}
+let lastRoute = {};
 
 function updateRender(vm) {
-  vm.router.normalize()
-  vm.route = vm.router.parse()
-  dom.body.setAttribute('data-page', vm.route.file)
+  vm.router.normalize();
+  vm.route = vm.router.parse();
+  dom.body.setAttribute('data-page', vm.route.file);
 }
 
 export function initRouter(vm) {
-  const config = vm.config
-  const mode = config.routerMode || 'hash'
-  let router
+  const config = vm.config;
+  const mode = config.routerMode || 'hash';
+  let router;
 
   if (mode === 'history' && supportsPushState) {
-    router = new HTML5History(config)
+    router = new HTML5History(config);
   } else {
-    router = new HashHistory(config)
+    router = new HashHistory(config);
   }
 
-  vm.router = router
-  updateRender(vm)
-  lastRoute = vm.route
+  vm.router = router;
+  updateRender(vm);
+  lastRoute = vm.route;
 
-  router.onchange(_ => {
-    updateRender(vm)
-    vm._updateRender()
+  // eslint-disable-next-line no-unused-vars
+  router.onchange(params => {
+    updateRender(vm);
+    vm._updateRender();
 
     if (lastRoute.path === vm.route.path) {
-      vm.$resetEvents()
-      return
+      vm.$resetEvents(params.source);
+      return;
     }
 
-    vm.$fetch()
-    lastRoute = vm.route
-  })
+    vm.$fetch(noop, vm.$resetEvents.bind(vm, params.source));
+    lastRoute = vm.route;
+  });
 }
diff --git a/src/core/router/util.js b/src/core/router/util.js
index 2ed88c58f..ba2eed8a1 100644
--- a/src/core/router/util.js
+++ b/src/core/router/util.js
@@ -1,76 +1,81 @@
-import {cached} from '../util/core'
+import { cached } from '../util/core';
 
-const decode = decodeURIComponent
-const encode = encodeURIComponent
+const decode = decodeURIComponent;
+const encode = encodeURIComponent;
 
 export function parseQuery(query) {
-  const res = {}
+  const res = {};
 
-  query = query.trim().replace(/^(\?|#|&)/, '')
+  query = query.trim().replace(/^(\?|#|&)/, '');
 
   if (!query) {
-    return res
+    return res;
   }
 
   // Simple parse
-  query.split('&').forEach(function (param) {
-    const parts = param.replace(/\+/g, ' ').split('=')
+  query.split('&').forEach(function(param) {
+    const parts = param.replace(/\+/g, ' ').split('=');
 
-    res[parts[0]] = parts[1] && decode(parts[1])
-  })
+    res[parts[0]] = parts[1] && decode(parts[1]);
+  });
 
-  return res
+  return res;
 }
 
 export function stringifyQuery(obj, ignores = []) {
-  const qs = []
+  const qs = [];
 
   for (const key in obj) {
     if (ignores.indexOf(key) > -1) {
-      continue
+      continue;
     }
+
     qs.push(
-      obj[key] ?
-        `${encode(key)}=${encode(obj[key])}`.toLowerCase() :
-        encode(key)
-    )
+      obj[key]
+        ? `${encode(key)}=${encode(obj[key])}`.toLowerCase()
+        : encode(key)
+    );
   }
 
-  return qs.length ? `?${qs.join('&')}` : ''
+  return qs.length ? `?${qs.join('&')}` : '';
 }
 
 export const isAbsolutePath = cached(path => {
-  return /(:|(\/{2}))/g.test(path)
-})
+  return /(:|(\/{2}))/g.test(path);
+});
 
 export const getParentPath = cached(path => {
-  return /\/$/g.test(path) ?
-    path :
-    (path = path.match(/(\S*\/)[^/]+$/)) ? path[1] : ''
-})
+  if (/\/$/g.test(path)) {
+    return path;
+  }
+
+  const matchingParts = path.match(/(\S*\/)[^/]+$/);
+  return matchingParts ? matchingParts[1] : '';
+});
 
 export const cleanPath = cached(path => {
-  return path.replace(/^\/+/, '/').replace(/([^:])\/{2,}/g, '$1/')
-})
+  return path.replace(/^\/+/, '/').replace(/([^:])\/{2,}/g, '$1/');
+});
 
 export const resolvePath = cached(path => {
-  const segments = path.replace(/^\//, '').split('/')
-  let resolved = []
+  const segments = path.replace(/^\//, '').split('/');
+  let resolved = [];
   for (let i = 0, len = segments.length; i < len; i++) {
-    const segment = segments[i]
+    const segment = segments[i];
     if (segment === '..') {
-      resolved.pop()
+      resolved.pop();
     } else if (segment !== '.') {
-      resolved.push(segment)
+      resolved.push(segment);
     }
   }
-  return '/' + resolved.join('/')
-})
+
+  return '/' + resolved.join('/');
+});
 
 export function getPath(...args) {
-  return cleanPath(args.join('/'))
+  return cleanPath(args.join('/'));
 }
 
 export const replaceSlug = cached(path => {
-  return path.replace('#', '?id=')
-})
+  return path.replace('#', '?id=');
+});
diff --git a/src/core/util/core.js b/src/core/util/core.js
index c538e2223..9d2638412 100644
--- a/src/core/util/core.js
+++ b/src/core/util/core.js
@@ -1,74 +1,68 @@
 /**
  * Create a cached version of a pure function.
+ * @param {*} fn The function call to be cached
+ * @void
  */
+
 export function cached(fn) {
-  const cache = Object.create(null)
-  return function (str) {
-    const key = isPrimitive(str) ? str : JSON.stringify(str)
-    const hit = cache[key]
-    return hit || (cache[key] = fn(str))
-  }
+  const cache = Object.create(null);
+  return function(str) {
+    const key = isPrimitive(str) ? str : JSON.stringify(str);
+    const hit = cache[key];
+    return hit || (cache[key] = fn(str));
+  };
 }
 
 /**
  * Hyphenate a camelCase string.
  */
 export const hyphenate = cached(str => {
-  return str.replace(/([A-Z])/g, m => '-' + m.toLowerCase())
-})
+  return str.replace(/([A-Z])/g, m => '-' + m.toLowerCase());
+});
 
-export const hasOwn = Object.prototype.hasOwnProperty
+export const hasOwn = Object.prototype.hasOwnProperty;
 
 /**
  * Simple Object.assign polyfill
+ * @param {Object} to The object to be merged with
+ * @returns {Object} The merged object
  */
 export const merge =
   Object.assign ||
-  function (to) {
+  function(to) {
     for (let i = 1; i < arguments.length; i++) {
-      const from = Object(arguments[i])
+      const from = Object(arguments[i]);
 
       for (const key in from) {
         if (hasOwn.call(from, key)) {
-          to[key] = from[key]
+          to[key] = from[key];
         }
       }
     }
 
-    return to
-  }
+    return to;
+  };
 
 /**
  * Check if value is primitive
+ * @param {*} value Checks if a value is primitive
+ * @returns {Boolean} Result of the check
  */
 export function isPrimitive(value) {
-  return typeof value === 'string' || typeof value === 'number'
+  return typeof value === 'string' || typeof value === 'number';
 }
 
 /**
- * Perform no operation.
+ * Performs no operation.
+ * @void
  */
 export function noop() {}
 
 /**
  * Check if value is function
+ * @param {*} obj Any javascript object
+ * @returns {Boolean} True if the passed-in value is a function
  */
 export function isFn(obj) {
-  return typeof obj === 'function'
+  return typeof obj === 'function';
 }
-
-/**
- * escape String
- */
-export function escapeString(string) {
-  const entityMap = {
-    '&': '&',
-    '<': '<',
-    '>': '>',
-    '"': '"',
-    '\'': ''',
-    '/': '/'
-  }
-
-  return String(string).replace(/[&<>"'/]/g, s => entityMap[s])
-}
\ No newline at end of file
diff --git a/src/core/util/dom.js b/src/core/util/dom.js
index 388927d11..b17628636 100644
--- a/src/core/util/dom.js
+++ b/src/core/util/dom.js
@@ -1,43 +1,50 @@
-import {isFn} from '../util/core'
-import {inBrowser} from './env'
+import { isFn } from '../util/core';
+import { inBrowser } from './env';
 
-const cacheNode = {}
+const cacheNode = {};
 
 /**
  * Get Node
- * @param  {String|Element} el
- * @param  {Boolean} noCache
- * @return {Element}
+ * @param  {String|Element} el A DOM element
+ * @param  {Boolean} noCache Flag to use or not use the cache
+ * @return {Element} The found node element
  */
 export function getNode(el, noCache = false) {
   if (typeof el === 'string') {
     if (typeof window.Vue !== 'undefined') {
-      return find(el)
+      return find(el);
     }
-    el = noCache ? find(el) : cacheNode[el] || (cacheNode[el] = find(el))
+
+    el = noCache ? find(el) : cacheNode[el] || (cacheNode[el] = find(el));
   }
 
-  return el
+  return el;
 }
 
-export const $ = inBrowser && document
+export const $ = inBrowser && document;
 
-export const body = inBrowser && $.body
+export const body = inBrowser && $.body;
 
-export const head = inBrowser && $.head
+export const head = inBrowser && $.head;
 
 /**
- * Find element
+ * Find elements
+ * @param {String|Element} el The root element where to perform the search from
+ * @param {Element} node The query
+ * @returns {Element} The found DOM element
  * @example
  * find('nav') => document.querySelector('nav')
  * find(nav, 'a') => nav.querySelector('a')
  */
 export function find(el, node) {
-  return node ? el.querySelector(node) : $.querySelector(el)
+  return node ? el.querySelector(node) : $.querySelector(el);
 }
 
 /**
  * Find all elements
+ * @param {String|Element} el The root element where to perform the search from
+ * @param {Element} node The query
+ * @returns {Array} An array of DOM elements
  * @example
  * findAll('a') => [].slice.call(document.querySelectorAll('a'))
  * findAll(nav, 'a') => [].slice.call(nav.querySelectorAll('a'))
@@ -45,48 +52,52 @@ export function find(el, node) {
 export function findAll(el, node) {
   return [].slice.call(
     node ? el.querySelectorAll(node) : $.querySelectorAll(el)
-  )
+  );
 }
 
 export function create(node, tpl) {
-  node = $.createElement(node)
+  node = $.createElement(node);
   if (tpl) {
-    node.innerHTML = tpl
+    node.innerHTML = tpl;
   }
-  return node
+
+  return node;
 }
 
 export function appendTo(target, el) {
-  return target.appendChild(el)
+  return target.appendChild(el);
 }
 
 export function before(target, el) {
-  return target.insertBefore(el, target.children[0])
+  return target.insertBefore(el, target.children[0]);
 }
 
 export function on(el, type, handler) {
-  isFn(type) ?
-    window.addEventListener(el, type) :
-    el.addEventListener(type, handler)
+  isFn(type)
+    ? window.addEventListener(el, type)
+    : el.addEventListener(type, handler);
 }
 
 export function off(el, type, handler) {
-  isFn(type) ?
-    window.removeEventListener(el, type) :
-    el.removeEventListener(type, handler)
+  isFn(type)
+    ? window.removeEventListener(el, type)
+    : el.removeEventListener(type, handler);
 }
 
 /**
  * Toggle class
- *
+ * @param {String|Element} el The element that needs the class to be toggled
+ * @param {Element} type The type of action to be performed on the classList (toggle by default)
+ * @param {String} val Name of the class to be toggled
+ * @void
  * @example
  * toggleClass(el, 'active') => el.classList.toggle('active')
  * toggleClass(el, 'add', 'active') => el.classList.add('active')
  */
 export function toggleClass(el, type, val) {
-  el && el.classList[val ? type : 'toggle'](val || type)
+  el && el.classList[val ? type : 'toggle'](val || type);
 }
 
 export function style(content) {
-  appendTo(head, create('style', content))
+  appendTo(head, create('style', content));
 }
diff --git a/src/core/util/env.js b/src/core/util/env.js
index cd5163558..015179c58 100644
--- a/src/core/util/env.js
+++ b/src/core/util/env.js
@@ -1,13 +1,13 @@
-export const inBrowser = !process.env.SSR
+export const inBrowser = !process.env.SSR;
 
-export const isMobile = inBrowser && document.body.clientWidth <= 600
+export const isMobile = inBrowser && document.body.clientWidth <= 600;
 
 /**
  * @see https://github.com/MoOx/pjax/blob/master/lib/is-supported.js
  */
 export const supportsPushState =
   inBrowser &&
-  (function () {
+  (function() {
     // Borrowed wholesale from https://github.com/defunkt/jquery-pjax
     return (
       window.history &&
@@ -17,5 +17,5 @@ export const supportsPushState =
       !navigator.userAgent.match(
         /((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/
       )
-    )
-  })()
+    );
+  })();
diff --git a/src/core/util/index.js b/src/core/util/index.js
index eba6598f5..444ea9d47 100644
--- a/src/core/util/index.js
+++ b/src/core/util/index.js
@@ -1,3 +1,3 @@
-export * from './core'
-export * from './env'
-export * from '../router/util'
+export * from './core';
+export * from './env';
+export * from '../router/util';
diff --git a/src/core/util/polyfill/css-vars.js b/src/core/util/polyfill/css-vars.js
index fb3a80a2b..34e201f28 100644
--- a/src/core/util/polyfill/css-vars.js
+++ b/src/core/util/polyfill/css-vars.js
@@ -1,36 +1,36 @@
-import * as dom from '../dom'
-import {get} from '../../fetch/ajax'
+import * as dom from '../dom';
+import { get } from '../../fetch/ajax';
 
 function replaceVar(block, color) {
   block.innerHTML = block.innerHTML.replace(
     /var\(\s*--theme-color.*?\)/g,
     color
-  )
+  );
 }
 
-export default function (color) {
+export default function(color) {
   // Variable support
   if (window.CSS && window.CSS.supports && window.CSS.supports('(--v:red)')) {
-    return
+    return;
   }
 
   const styleBlocks = dom.findAll('style:not(.inserted),link');
   [].forEach.call(styleBlocks, block => {
     if (block.nodeName === 'STYLE') {
-      replaceVar(block, color)
+      replaceVar(block, color);
     } else if (block.nodeName === 'LINK') {
-      const href = block.getAttribute('href')
+      const href = block.getAttribute('href');
 
       if (!/\.css$/.test(href)) {
-        return
+        return;
       }
 
       get(href).then(res => {
-        const style = dom.create('style', res)
+        const style = dom.create('style', res);
 
-        dom.head.appendChild(style)
-        replaceVar(style, color)
-      })
+        dom.head.appendChild(style);
+        replaceVar(style, color);
+      });
     }
-  })
+  });
 }
diff --git a/src/plugins/disqus.js b/src/plugins/disqus.js
index dba7aef82..4355692ec 100644
--- a/src/plugins/disqus.js
+++ b/src/plugins/disqus.js
@@ -1,51 +1,52 @@
-const fixedPath = location.href.replace('/-/', '/#/')
+/* eslint-disable no-unused-vars */
+const fixedPath = location.href.replace('/-/', '/#/');
 if (fixedPath !== location.href) {
-  location.href = fixedPath
+  location.href = fixedPath;
 }
 
 function install(hook, vm) {
-  const dom = Docsify.dom
-  const disqus = vm.config.disqus
+  const dom = Docsify.dom;
+  const disqus = vm.config.disqus;
   if (!disqus) {
-    throw Error('$docsify.disqus is required')
+    throw Error('$docsify.disqus is required');
   }
 
   hook.init(_ => {
-    const script = dom.create('script')
+    const script = dom.create('script');
 
-    script.async = true
-    script.src = `https://${disqus}.disqus.com/embed.js`
-    script.setAttribute('data-timestamp', Number(new Date()))
-    dom.appendTo(dom.body, script)
-  })
+    script.async = true;
+    script.src = `https://${disqus}.disqus.com/embed.js`;
+    script.setAttribute('data-timestamp', Number(new Date()));
+    dom.appendTo(dom.body, script);
+  });
 
   hook.mounted(_ => {
-    const div = dom.create('div')
-    div.id = 'disqus_thread'
-    const main = dom.getNode('#main')
-    div.style = `width: ${main.clientWidth}px; margin: 0 auto 20px;`
-    dom.appendTo(dom.find('.content'), div)
+    const div = dom.create('div');
+    div.id = 'disqus_thread';
+    const main = dom.getNode('#main');
+    div.style = `width: ${main.clientWidth}px; margin: 0 auto 20px;`;
+    dom.appendTo(dom.find('.content'), div);
 
     // eslint-disable-next-line
     window.disqus_config = function() {
-      this.page.url = location.origin + '/-' + vm.route.path
-      this.page.identifier = vm.route.path
-      this.page.title = document.title
-    }
-  })
+      this.page.url = location.origin + '/-' + vm.route.path;
+      this.page.identifier = vm.route.path;
+      this.page.title = document.title;
+    };
+  });
 
   hook.doneEach(_ => {
     if (typeof window.DISQUS !== 'undefined') {
       window.DISQUS.reset({
         reload: true,
-        config: function () {
-          this.page.url = location.origin + '/-' + vm.route.path
-          this.page.identifier = vm.route.path
-          this.page.title = document.title
-        }
-      })
+        config: function() {
+          this.page.url = location.origin + '/-' + vm.route.path;
+          this.page.identifier = vm.route.path;
+          this.page.title = document.title;
+        },
+      });
     }
-  })
+  });
 }
 
-$docsify.plugins = [].concat(install, $docsify.plugins)
+$docsify.plugins = [].concat(install, $docsify.plugins);
diff --git a/src/plugins/emoji.js b/src/plugins/emoji.js
index e65e42c4b..2898c3d04 100644
--- a/src/plugins/emoji.js
+++ b/src/plugins/emoji.js
@@ -1508,17 +1508,17 @@ const AllGithubEmoji = [
   'zero',
   'zimbabwe',
   'zipper_mouth_face',
-  'zzz'
-]
+  'zzz',
+];
 
 // Emoji from All-Github-Emoji-Icons
 // https://github.com/scotch-io/All-Github-Emoji-Icons
-window.emojify = function (match, $1) {
-  return AllGithubEmoji.indexOf($1) === -1 ?
-    match :
-    '
'
-}
+        '" />';
+};
diff --git a/src/plugins/external-script.js b/src/plugins/external-script.js
index 2954030a1..f8bf9175f 100644
--- a/src/plugins/external-script.js
+++ b/src/plugins/external-script.js
@@ -1,25 +1,25 @@
 function handleExternalScript() {
-  const container = Docsify.dom.getNode('#main')
-  const scripts = Docsify.dom.findAll(container, 'script')
+  const container = Docsify.dom.getNode('#main');
+  const scripts = Docsify.dom.findAll(container, 'script');
 
-  for (let i = scripts.length; i--;) {
-    const script = scripts[i]
+  for (let i = scripts.length; i--; ) {
+    const script = scripts[i];
 
     if (script && script.src) {
-      const newScript = document.createElement('script')
+      const newScript = document.createElement('script');
 
       Array.prototype.slice.call(script.attributes).forEach(attribute => {
-        newScript[attribute.name] = attribute.value
-      })
+        newScript[attribute.name] = attribute.value;
+      });
 
-      script.parentNode.insertBefore(newScript, script)
-      script.parentNode.removeChild(script)
+      script.parentNode.insertBefore(newScript, script);
+      script.parentNode.removeChild(script);
     }
   }
 }
 
-const install = function (hook) {
-  hook.doneEach(handleExternalScript)
-}
+const install = function(hook) {
+  hook.doneEach(handleExternalScript);
+};
 
-window.$docsify.plugins = [].concat(install, window.$docsify.plugins)
+window.$docsify.plugins = [].concat(install, window.$docsify.plugins);
diff --git a/src/plugins/front-matter/index.js b/src/plugins/front-matter/index.js
index cb90ed91f..e91c4efc3 100644
--- a/src/plugins/front-matter/index.js
+++ b/src/plugins/front-matter/index.js
@@ -1,13 +1,13 @@
-import parser from './parser'
+import parser from './parser';
 
-const install = function (hook, vm) {
+const install = function(hook, vm) {
   hook.beforeEach(content => {
-    const {attributes, body} = parser(content)
+    const { attributes, body } = parser(content);
 
-    vm.frontmatter = attributes
+    vm.frontmatter = attributes;
 
-    return body
-  })
-}
+    return body;
+  });
+};
 
-$docsify.plugins = [].concat(install, $docsify.plugins)
+$docsify.plugins = [].concat(install, $docsify.plugins);
diff --git a/src/plugins/ga.js b/src/plugins/ga.js
index 2d6419bbf..2a6474ac0 100644
--- a/src/plugins/ga.js
+++ b/src/plugins/ga.js
@@ -1,38 +1,40 @@
+/* eslint-disable no-console */
 // From https://github.com/egoist/vue-ga/blob/master/src/index.js
 function appendScript() {
-  const script = document.createElement('script')
-  script.async = true
-  script.src = 'https://www.google-analytics.com/analytics.js'
-  document.body.appendChild(script)
+  const script = document.createElement('script');
+  script.async = true;
+  script.src = 'https://www.google-analytics.com/analytics.js';
+  document.body.appendChild(script);
 }
 
 function init(id) {
-  appendScript()
+  appendScript();
   window.ga =
     window.ga ||
-    function () {
-      (window.ga.q = window.ga.q || []).push(arguments)
-    }
-  window.ga.l = Number(new Date())
-  window.ga('create', id, 'auto')
+    function() {
+      (window.ga.q = window.ga.q || []).push(arguments);
+    };
+
+  window.ga.l = Number(new Date());
+  window.ga('create', id, 'auto');
 }
 
 function collect() {
   if (!window.ga) {
-    init($docsify.ga)
+    init($docsify.ga);
   }
 
-  window.ga('set', 'page', location.hash)
-  window.ga('send', 'pageview')
+  window.ga('set', 'page', location.hash);
+  window.ga('send', 'pageview');
 }
 
-const install = function (hook) {
+const install = function(hook) {
   if (!$docsify.ga) {
-    console.error('[Docsify] ga is required.')
-    return
+    console.error('[Docsify] ga is required.');
+    return;
   }
 
-  hook.beforeEach(collect)
-}
+  hook.beforeEach(collect);
+};
 
-$docsify.plugins = [].concat(install, $docsify.plugins)
+$docsify.plugins = [].concat(install, $docsify.plugins);
diff --git a/src/plugins/gitalk.js b/src/plugins/gitalk.js
index 8ba9acec6..b8d5f46e4 100644
--- a/src/plugins/gitalk.js
+++ b/src/plugins/gitalk.js
@@ -1,23 +1,24 @@
+/* eslint-disable no-unused-vars */
 function install(hook) {
-  const dom = Docsify.dom
+  const dom = Docsify.dom;
 
   hook.mounted(_ => {
-    const div = dom.create('div')
-    div.id = 'gitalk-container'
-    const main = dom.getNode('#main')
-    div.style = `width: ${main.clientWidth}px; margin: 0 auto 20px;`
-    dom.appendTo(dom.find('.content'), div)
-  })
+    const div = dom.create('div');
+    div.id = 'gitalk-container';
+    const main = dom.getNode('#main');
+    div.style = `width: ${main.clientWidth}px; margin: 0 auto 20px;`;
+    dom.appendTo(dom.find('.content'), div);
+  });
 
   hook.doneEach(_ => {
-    const el = document.getElementById('gitalk-container')
+    const el = document.getElementById('gitalk-container');
     while (el.hasChildNodes()) {
-      el.removeChild(el.firstChild)
+      el.removeChild(el.firstChild);
     }
 
     // eslint-disable-next-line
-    gitalk.render('gitalk-container')
-  })
+    gitalk.render('gitalk-container');
+  });
 }
 
-$docsify.plugins = [].concat(install, $docsify.plugins)
+$docsify.plugins = [].concat(install, $docsify.plugins);
diff --git a/src/plugins/matomo.js b/src/plugins/matomo.js
index 7b61cba7c..2074be767 100644
--- a/src/plugins/matomo.js
+++ b/src/plugins/matomo.js
@@ -1,37 +1,39 @@
 function appendScript(options) {
-  const script = document.createElement('script')
-  script.async = true
-  script.src = options.host + '/matomo.js'
-  document.body.appendChild(script)
+  const script = document.createElement('script');
+  script.async = true;
+  script.src = options.host + '/matomo.js';
+  document.body.appendChild(script);
 }
 
 function init(options) {
-  window._paq = window._paq || []
-  window._paq.push(['trackPageView'])
-  window._paq.push(['enableLinkTracking'])
+  window._paq = window._paq || [];
+  window._paq.push(['trackPageView']);
+  window._paq.push(['enableLinkTracking']);
   setTimeout(function() {
-    appendScript(options)
-    window._paq.push(['setTrackerUrl', options.host + '/matomo.php'])
-    window._paq.push(['setSiteId', options.id + ''])
-  }, 0)
+    appendScript(options);
+    window._paq.push(['setTrackerUrl', options.host + '/matomo.php']);
+    window._paq.push(['setSiteId', String(options.id)]);
+  }, 0);
 }
 
 function collect() {
   if (!window._paq) {
-    init($docsify.matomo)
+    init($docsify.matomo);
   }
-  window._paq.push(['setCustomUrl',  window.location.hash.substr(1)])
-  window._paq.push(['setDocumentTitle', document.title])
-  window._paq.push(['trackPageView'])
+
+  window._paq.push(['setCustomUrl', window.location.hash.substr(1)]);
+  window._paq.push(['setDocumentTitle', document.title]);
+  window._paq.push(['trackPageView']);
 }
 
-const install = function (hook) {
+const install = function(hook) {
   if (!$docsify.matomo) {
-    console.error('[Docsify] matomo is required.')
-    return
+    // eslint-disable-next-line no-console
+    console.error('[Docsify] matomo is required.');
+    return;
   }
 
-  hook.beforeEach(collect)
-}
+  hook.beforeEach(collect);
+};
 
-$docsify.plugins = [].concat(install, $docsify.plugins)
+$docsify.plugins = [].concat(install, $docsify.plugins);
diff --git a/src/plugins/search/component.js b/src/plugins/search/component.js
index 4daf5fd3e..21add7ef2 100644
--- a/src/plugins/search/component.js
+++ b/src/plugins/search/component.js
@@ -1,7 +1,8 @@
-import {search} from './search'
+/* eslint-disable no-unused-vars */
+import { search } from './search';
 
-let NO_DATA_TEXT = ''
-let options
+let NO_DATA_TEXT = '';
+let options;
 
 function style() {
   const code = `
@@ -97,14 +98,13 @@ function style() {
 
 .app-name.hide, .sidebar-nav.hide {
   display: none;
-}`
+}`;
 
-  Docsify.dom.style(code)
+  Docsify.dom.style(code);
 }
 
 function tpl(defaultValue = '') {
-  const html =
-    ``
-  const el = Docsify.dom.create('div', html)
-  const aside = Docsify.dom.find('aside')
+    `;
+  const el = Docsify.dom.create('div', html);
+  const aside = Docsify.dom.find('aside');
 
-  Docsify.dom.toggleClass(el, 'search')
-  Docsify.dom.before(aside, el)
+  Docsify.dom.toggleClass(el, 'search');
+  Docsify.dom.before(aside, el);
 }
 
 function doSearch(value) {
-  const $search = Docsify.dom.find('div.search')
-  const $panel = Docsify.dom.find($search, '.results-panel')
-  const $clearBtn = Docsify.dom.find($search, '.clear-button')
-  const $sidebarNav = Docsify.dom.find('.sidebar-nav')
-  const $appName = Docsify.dom.find('.app-name')
+  const $search = Docsify.dom.find('div.search');
+  const $panel = Docsify.dom.find($search, '.results-panel');
+  const $clearBtn = Docsify.dom.find($search, '.clear-button');
+  const $sidebarNav = Docsify.dom.find('.sidebar-nav');
+  const $appName = Docsify.dom.find('.app-name');
 
   if (!value) {
-    $panel.classList.remove('show')
-    $clearBtn.classList.remove('show')
-    $panel.innerHTML = ''
+    $panel.classList.remove('show');
+    $clearBtn.classList.remove('show');
+    $panel.innerHTML = '';
 
     if (options.hideOtherSidebarContent) {
-      $sidebarNav.classList.remove('hide')
-      $appName.classList.remove('hide')
+      $sidebarNav.classList.remove('hide');
+      $appName.classList.remove('hide');
     }
-    return
+
+    return;
   }
-  const matchs = search(value)
 
-  let html = ''
+  const matchs = search(value);
+
+  let html = '';
   matchs.forEach(post => {
     html += ``
-  })
+`;
+  });
 
-  $panel.classList.add('show')
-  $clearBtn.classList.add('show')
-  $panel.innerHTML = html || `${NO_DATA_TEXT}
`
+  $panel.classList.add('show');
+  $clearBtn.classList.add('show');
+  $panel.innerHTML = html || `${NO_DATA_TEXT}
`;
   if (options.hideOtherSidebarContent) {
-    $sidebarNav.classList.add('hide')
-    $appName.classList.add('hide')
+    $sidebarNav.classList.add('hide');
+    $appName.classList.add('hide');
   }
 }
 
 function bindEvents() {
-  const $search = Docsify.dom.find('div.search')
-  const $input = Docsify.dom.find($search, 'input')
-  const $inputWrap = Docsify.dom.find($search, '.input-wrap')
+  const $search = Docsify.dom.find('div.search');
+  const $input = Docsify.dom.find($search, 'input');
+  const $inputWrap = Docsify.dom.find($search, '.input-wrap');
 
-  let timeId
+  let timeId;
   // Prevent to Fold sidebar
   Docsify.dom.on(
     $search,
     'click',
     e => e.target.tagName !== 'A' && e.stopPropagation()
-  )
+  );
   Docsify.dom.on($input, 'input', e => {
-    clearTimeout(timeId)
-    timeId = setTimeout(_ => doSearch(e.target.value.trim()), 100)
-  })
+    clearTimeout(timeId);
+    timeId = setTimeout(_ => doSearch(e.target.value.trim()), 100);
+  });
   Docsify.dom.on($inputWrap, 'click', e => {
     // Click input outside
     if (e.target.tagName !== 'INPUT') {
-      $input.value = ''
-      doSearch()
+      $input.value = '';
+      doSearch();
     }
-  })
+  });
 }
 
 function updatePlaceholder(text, path) {
-  const $input = Docsify.dom.getNode('.search input[type="search"]')
+  const $input = Docsify.dom.getNode('.search input[type="search"]');
 
   if (!$input) {
-    return
+    return;
   }
+
   if (typeof text === 'string') {
-    $input.placeholder = text
+    $input.placeholder = text;
   } else {
-    const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0]
-    $input.placeholder = text[match]
+    const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0];
+    $input.placeholder = text[match];
   }
 }
 
 function updateNoData(text, path) {
   if (typeof text === 'string') {
-    NO_DATA_TEXT = text
+    NO_DATA_TEXT = text;
   } else {
-    const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0]
-    NO_DATA_TEXT = text[match]
+    const match = Object.keys(text).filter(key => path.indexOf(key) > -1)[0];
+    NO_DATA_TEXT = text[match];
   }
 }
 
 function updateOptions(opts) {
-  options = opts
+  options = opts;
 }
 
 export function init(opts, vm) {
-  const keywords = vm.router.parse().query.s
+  const keywords = vm.router.parse().query.s;
 
-  updateOptions(opts)
-  style()
-  tpl(keywords)
-  bindEvents()
-  keywords && setTimeout(_ => doSearch(keywords), 500)
+  updateOptions(opts);
+  style();
+  tpl(keywords);
+  bindEvents();
+  keywords && setTimeout(_ => doSearch(keywords), 500);
 }
 
 export function update(opts, vm) {
-  updateOptions(opts)
-  updatePlaceholder(opts.placeholder, vm.route.path)
-  updateNoData(opts.noData, vm.route.path)
+  updateOptions(opts);
+  updatePlaceholder(opts.placeholder, vm.route.path);
+  updateNoData(opts.noData, vm.route.path);
 }
diff --git a/src/plugins/search/index.js b/src/plugins/search/index.js
index bbd3af6f0..3bfd3b6b5 100644
--- a/src/plugins/search/index.js
+++ b/src/plugins/search/index.js
@@ -1,5 +1,6 @@
-import {init as initComponet, update as updateComponent} from './component'
-import {init as initSearch} from './search'
+/* eslint-disable no-unused-vars */
+import { init as initComponet, update as updateComponent } from './component';
+import { init as initSearch } from './search';
 
 const CONFIG = {
   placeholder: 'Type to search',
@@ -8,35 +9,36 @@ const CONFIG = {
   depth: 2,
   maxAge: 86400000, // 1 day
   hideOtherSidebarContent: false,
-  namespace: undefined
-}
+  namespace: undefined,
+};
 
-const install = function (hook, vm) {
-  const {util} = Docsify
-  const opts = vm.config.search || CONFIG
+const install = function(hook, vm) {
+  const { util } = Docsify;
+  const opts = vm.config.search || CONFIG;
 
   if (Array.isArray(opts)) {
-    CONFIG.paths = opts
+    CONFIG.paths = opts;
   } else if (typeof opts === 'object') {
-    CONFIG.paths = Array.isArray(opts.paths) ? opts.paths : 'auto'
-    CONFIG.maxAge = util.isPrimitive(opts.maxAge) ? opts.maxAge : CONFIG.maxAge
-    CONFIG.placeholder = opts.placeholder || CONFIG.placeholder
-    CONFIG.noData = opts.noData || CONFIG.noData
-    CONFIG.depth = opts.depth || CONFIG.depth
-    CONFIG.hideOtherSidebarContent = opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent
-    CONFIG.namespace = opts.namespace || CONFIG.namespace
+    CONFIG.paths = Array.isArray(opts.paths) ? opts.paths : 'auto';
+    CONFIG.maxAge = util.isPrimitive(opts.maxAge) ? opts.maxAge : CONFIG.maxAge;
+    CONFIG.placeholder = opts.placeholder || CONFIG.placeholder;
+    CONFIG.noData = opts.noData || CONFIG.noData;
+    CONFIG.depth = opts.depth || CONFIG.depth;
+    CONFIG.hideOtherSidebarContent =
+      opts.hideOtherSidebarContent || CONFIG.hideOtherSidebarContent;
+    CONFIG.namespace = opts.namespace || CONFIG.namespace;
   }
 
-  const isAuto = CONFIG.paths === 'auto'
+  const isAuto = CONFIG.paths === 'auto';
 
   hook.mounted(_ => {
-    initComponet(CONFIG, vm)
-    !isAuto && initSearch(CONFIG, vm)
-  })
+    initComponet(CONFIG, vm);
+    !isAuto && initSearch(CONFIG, vm);
+  });
   hook.doneEach(_ => {
-    updateComponent(CONFIG, vm)
-    isAuto && initSearch(CONFIG, vm)
-  })
-}
+    updateComponent(CONFIG, vm);
+    isAuto && initSearch(CONFIG, vm);
+  });
+};
 
-$docsify.plugins = [].concat(install, $docsify.plugins)
+$docsify.plugins = [].concat(install, $docsify.plugins);
diff --git a/src/plugins/search/search.js b/src/plugins/search/search.js
index 2c9febfbc..29d74b79e 100644
--- a/src/plugins/search/search.js
+++ b/src/plugins/search/search.js
@@ -1,15 +1,21 @@
-let INDEXS = {}
+/* eslint-disable no-unused-vars */
+let INDEXS = {};
 
 const LOCAL_STORAGE = {
   EXPIRE_KEY: 'docsify.search.expires',
-  INDEX_KEY: 'docsify.search.index'
-}
+  INDEX_KEY: 'docsify.search.index',
+};
 
 function resolveExpireKey(namespace) {
-  return namespace ? `${LOCAL_STORAGE.EXPIRE_KEY}/${namespace}` : LOCAL_STORAGE.EXPIRE_KEY
+  return namespace
+    ? `${LOCAL_STORAGE.EXPIRE_KEY}/${namespace}`
+    : LOCAL_STORAGE.EXPIRE_KEY;
 }
+
 function resolveIndexKey(namespace) {
-  return namespace ? `${LOCAL_STORAGE.INDEX_KEY}/${namespace}` : LOCAL_STORAGE.INDEX_KEY
+  return namespace
+    ? `${LOCAL_STORAGE.INDEX_KEY}/${namespace}`
+    : LOCAL_STORAGE.INDEX_KEY;
 }
 
 function escapeHtml(string) {
@@ -18,117 +24,132 @@ function escapeHtml(string) {
     '<': '<',
     '>': '>',
     '"': '"',
-    '\'': ''',
-    '/': '/'
-  }
+    "'": ''',
+    '/': '/',
+  };
 
-  return String(string).replace(/[&<>"'/]/g, s => entityMap[s])
+  return String(string).replace(/[&<>"'/]/g, s => entityMap[s]);
 }
 
 function getAllPaths(router) {
-  const paths = []
-
-  Docsify.dom.findAll('.sidebar-nav a:not(.section-link):not([data-nosearch])').forEach(node => {
-    const href = node.href
-    const originHref = node.getAttribute('href')
-    const path = router.parse(href).path
-
-    if (
-      path &&
-      paths.indexOf(path) === -1 &&
-      !Docsify.util.isAbsolutePath(originHref)
-    ) {
-      paths.push(path)
-    }
-  })
+  const paths = [];
+
+  Docsify.dom
+    .findAll('.sidebar-nav a:not(.section-link):not([data-nosearch])')
+    .forEach(node => {
+      const href = node.href;
+      const originHref = node.getAttribute('href');
+      const path = router.parse(href).path;
+
+      if (
+        path &&
+        paths.indexOf(path) === -1 &&
+        !Docsify.util.isAbsolutePath(originHref)
+      ) {
+        paths.push(path);
+      }
+    });
 
-  return paths
+  return paths;
 }
 
 function saveData(maxAge, expireKey, indexKey) {
-  localStorage.setItem(expireKey, Date.now() + maxAge)
-  localStorage.setItem(indexKey, JSON.stringify(INDEXS))
+  localStorage.setItem(expireKey, Date.now() + maxAge);
+  localStorage.setItem(indexKey, JSON.stringify(INDEXS));
 }
 
 export function genIndex(path, content = '', router, depth) {
-  const tokens = window.marked.lexer(content)
-  const slugify = window.Docsify.slugify
-  const index = {}
-  let slug
+  const tokens = window.marked.lexer(content);
+  const slugify = window.Docsify.slugify;
+  const index = {};
+  let slug;
 
   tokens.forEach(token => {
     if (token.type === 'heading' && token.depth <= depth) {
-      slug = router.toURL(path, {id: slugify(token.text)})
-      index[slug] = {slug, title: token.text, body: ''}
+      slug = router.toURL(path, { id: slugify(token.text) });
+      index[slug] = { slug, title: token.text, body: '' };
     } else {
       if (!slug) {
-        return
+        return;
       }
+
       if (!index[slug]) {
-        index[slug] = {slug, title: '', body: ''}
+        index[slug] = { slug, title: '', body: '' };
       } else if (index[slug].body) {
-        index[slug].body += '\n' + (token.text || '')
+        index[slug].body += '\n' + (token.text || '');
       } else {
-        index[slug].body = token.text
+        if (!token.text) {
+          if (token.type === 'table') {
+            token.text = token.cells
+              .map(function(rows) {
+                return rows.join(' | ');
+              })
+              .join(' |\n ');
+          }
+        }
+
+        index[slug].body = index[slug].body
+          ? index[slug].body + token.text
+          : token.text;
       }
     }
-  })
-  slugify.clear()
-  return index
+  });
+  slugify.clear();
+  return index;
 }
 
 /**
- * @param {String} query
- * @returns {Array}
+ * @param {String} query Search query
+ * @returns {Array} Array of results
  */
 export function search(query) {
-  const matchingResults = []
-  let data = []
+  const matchingResults = [];
+  let data = [];
   Object.keys(INDEXS).forEach(key => {
-    data = data.concat(Object.keys(INDEXS[key]).map(page => INDEXS[key][page]))
-  })
+    data = data.concat(Object.keys(INDEXS[key]).map(page => INDEXS[key][page]));
+  });
 
-  query = query.trim()
-  let keywords = query.split(/[\s\-,\\/]+/)
+  query = query.trim();
+  let keywords = query.split(/[\s\-,\\/]+/);
   if (keywords.length !== 1) {
-    keywords = [].concat(query, keywords)
+    keywords = [].concat(query, keywords);
   }
 
   for (let i = 0; i < data.length; i++) {
-    const post = data[i]
-    let matchesScore = 0
-    let resultStr = ''
-    const postTitle = post.title && post.title.trim()
-    const postContent = post.body && post.body.trim()
-    const postUrl = post.slug || ''
+    const post = data[i];
+    let matchesScore = 0;
+    let resultStr = '';
+    const postTitle = post.title && post.title.trim();
+    const postContent = post.body && post.body.trim();
+    const postUrl = post.slug || '';
 
     if (postTitle) {
-      keywords.forEach( keyword => {
+      keywords.forEach(keyword => {
         // From https://github.com/sindresorhus/escape-string-regexp
         const regEx = new RegExp(
           keyword.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&'),
           'gi'
         );
-        let indexTitle = -1
-        let indexContent = -1
+        let indexTitle = -1;
+        let indexContent = -1;
 
-        indexTitle = postTitle ? postTitle.search(regEx) : -1
-        indexContent = postContent ? postContent.search(regEx) : -1
+        indexTitle = postTitle ? postTitle.search(regEx) : -1;
+        indexContent = postContent ? postContent.search(regEx) : -1;
 
         if (indexTitle >= 0 || indexContent >= 0) {
           matchesScore += indexTitle >= 0 ? 3 : indexContent >= 0 ? 2 : 0;
           if (indexContent < 0) {
-            indexContent = 0
+            indexContent = 0;
           }
 
-          let start = 0
-          let end = 0
+          let start = 0;
+          let end = 0;
 
-          start = indexContent < 11 ? 0 : indexContent - 10
-          end = start === 0 ? 70 : indexContent + keyword.length + 60
+          start = indexContent < 11 ? 0 : indexContent - 10;
+          end = start === 0 ? 70 : indexContent + keyword.length + 60;
 
-          if (end > postContent.length) {
-            end = postContent.length
+          if (postContent && end > postContent.length) {
+            end = postContent.length;
           }
 
           const matchContent =
@@ -136,21 +157,21 @@ export function search(query) {
             escapeHtml(postContent)
               .substring(start, end)
               .replace(regEx, `${keyword}`) +
-            '...'
+            '...';
 
-          resultStr += matchContent
+          resultStr += matchContent;
         }
-      })
+      });
 
       if (matchesScore > 0) {
         const matchingPost = {
           title: escapeHtml(postTitle),
           content: postContent ? resultStr : '',
           url: postUrl,
-          score: matchesScore
-        }
+          score: matchesScore,
+        };
 
-        matchingResults.push(matchingPost)
+        matchingResults.push(matchingPost);
       }
     }
   }
@@ -159,35 +180,35 @@ export function search(query) {
 }
 
 export function init(config, vm) {
-  const isAuto = config.paths === 'auto'
+  const isAuto = config.paths === 'auto';
 
-  const expireKey = resolveExpireKey(config.namespace)
-  const indexKey = resolveIndexKey(config.namespace)
+  const expireKey = resolveExpireKey(config.namespace);
+  const indexKey = resolveIndexKey(config.namespace);
 
-  const isExpired = localStorage.getItem(expireKey) < Date.now()
+  const isExpired = localStorage.getItem(expireKey) < Date.now();
 
-  INDEXS = JSON.parse(localStorage.getItem(indexKey))
+  INDEXS = JSON.parse(localStorage.getItem(indexKey));
 
   if (isExpired) {
-    INDEXS = {}
+    INDEXS = {};
   } else if (!isAuto) {
-    return
+    return;
   }
 
-  const paths = isAuto ? getAllPaths(vm.router) : config.paths
-  const len = paths.length
-  let count = 0
+  const paths = isAuto ? getAllPaths(vm.router) : config.paths;
+  const len = paths.length;
+  let count = 0;
 
   paths.forEach(path => {
     if (INDEXS[path]) {
-      return count++
+      return count++;
     }
 
-    Docsify
-      .get(vm.router.getFile(path), false, vm.config.requestHeaders)
-      .then(result => {
-        INDEXS[path] = genIndex(path, result, vm.router, config.depth)
-        len === ++count && saveData(config.maxAge, expireKey, indexKey)
-      })
-  })
+    Docsify.get(vm.router.getFile(path), false, vm.config.requestHeaders).then(
+      result => {
+        INDEXS[path] = genIndex(path, result, vm.router, config.depth);
+        len === ++count && saveData(config.maxAge, expireKey, indexKey);
+      }
+    );
+  });
 }
diff --git a/src/plugins/zoom-image.js b/src/plugins/zoom-image.js
index faf92e1dd..f227e9fee 100644
--- a/src/plugins/zoom-image.js
+++ b/src/plugins/zoom-image.js
@@ -1,21 +1,30 @@
-import mediumZoom from 'medium-zoom'
+/* eslint-disable no-unused-vars */
+import mediumZoom from 'medium-zoom';
 
-const matchesSelector = Element.prototype.matches || Element.prototype.webkitMatchesSelector || Element.prototype.msMatchesSelector
+const matchesSelector =
+  Element.prototype.matches ||
+  Element.prototype.webkitMatchesSelector ||
+  Element.prototype.msMatchesSelector;
 
 function install(hook) {
-  let zoom
+  let zoom;
 
   hook.doneEach(_ => {
-    let elms = Array.apply(null, document.querySelectorAll('.markdown-section img:not(.emoji):not([data-no-zoom])'))
+    let elms = Array.apply(
+      null,
+      document.querySelectorAll(
+        '.markdown-section img:not(.emoji):not([data-no-zoom])'
+      )
+    );
 
-    elms = elms.filter(elm => matchesSelector.call(elm, 'a img') === false)
+    elms = elms.filter(elm => matchesSelector.call(elm, 'a img') === false);
 
     if (zoom) {
-      zoom.detach()
+      zoom.detach();
     }
 
-    zoom = mediumZoom(elms)
-  })
+    zoom = mediumZoom(elms);
+  });
 }
 
-$docsify.plugins = [].concat(install, $docsify.plugins)
+$docsify.plugins = [].concat(install, $docsify.plugins);
diff --git a/src/themes/basic/_layout.styl b/src/themes/basic/_layout.styl
index 387fd7994..3d6d5c33b 100644
--- a/src/themes/basic/_layout.styl
+++ b/src/themes/basic/_layout.styl
@@ -120,6 +120,7 @@ li input[type='checkbox']
     margin 0 1rem
     padding 5px 0
     position relative
+    cursor pointer
 
     ul
       background-color #fff
@@ -277,8 +278,9 @@ main.hidden
   transition opacity 0.3s
   width $sidebar-width - 16px
   z-index 30
+  cursor pointer
 
-  .sidebar-toggle-button:hover
+  &:hover .sidebar-toggle-button
     opacity 0.4
 
   span
@@ -305,7 +307,7 @@ body.sticky
 /* markdown content found on pages */
 .markdown-section
   margin 0 auto
-  max-width 800px
+  max-width 80%
   padding 30px 15px 40px 15px
   position relative
 
diff --git a/test/_helper.js b/test/_helper.js
index 4b4abce89..afd0c07fd 100644
--- a/test/_helper.js
+++ b/test/_helper.js
@@ -1,23 +1,31 @@
-// load ES6 modules in Node.js on the fly
-require = require('esm')(module/*, options*/)
+/* eslint-disable no-global-assign */
+// Load ES6 modules in Node.js on the fly
+require = require('esm')(
+  module /* , options */
+); /* eslint-disable-line no-global-assign */
 
-const path = require('path')
-const {expect} = require('chai')
+const path = require('path');
+const { expect } = require('chai');
 
-const {JSDOM} = require('jsdom')
+const { JSDOM } = require('jsdom');
 
 function ready(callback) {
-  const state = document.readyState
+  const state = document.readyState;
 
   if (state === 'complete' || state === 'interactive') {
-    return setTimeout(callback, 0)
+    return setTimeout(callback, 0);
   }
 
-  document.addEventListener('DOMContentLoaded', callback)
+  document.addEventListener('DOMContentLoaded', callback);
 }
-module.exports.init = function(fixture = 'default', config = {}, markup) {
-	if (markup == null) {
-		markup = `
+
+module.exports.init = function(
+  fixture = 'default',
+  config = {},
+  markup = null
+) {
+  if (markup === null || markup === undefined) {
+    markup = `
 		
 		  
 		  
@@ -26,62 +34,67 @@ module.exports.init = function(fixture = 'default', config = {}, markup) {
 		  		window.$docsify = ${JSON.stringify(config, null, 2)}
 		  	
 		  
-		`
-	}
-	const rootPath = path.join(__dirname, 'fixtures', fixture)
-		
-	const dom = new JSDOM(markup) 
-	dom.reconfigure({ url: 'file:///' + rootPath })
-
-	global.window = dom.window
-	global.document = dom.window.document
-	global.navigator = dom.window.navigator
-	global.location = dom.window.location
-	global.XMLHttpRequest = dom.window.XMLHttpRequest
-
-	// mimic src/core/index.js but for Node.js
-	function Docsify() {
-	  this._init()
-	}
-
-	const proto = Docsify.prototype
-
-	const {initMixin} = require('../src/core/init')
-	const {routerMixin} = require('../src/core//router')
-	const {renderMixin} = require('../src/core//render')
-	const {fetchMixin} = require('../src/core/fetch')
-	const {eventMixin} = require('../src/core//event')
-
-	initMixin(proto)
-	routerMixin(proto)
-	renderMixin(proto)
-	fetchMixin(proto)
-	eventMixin(proto)
-
-	const NOT_INIT_PATTERN = ''
-
-	return new Promise((resolve, reject) => {
-		ready(() => {
-			const docsify = new Docsify()
-			// NOTE: I was not able to get it working with a callback, but polling works usually at the first time
-			const id = setInterval(() => {
-				if (dom.window.document.body.innerHTML.indexOf(NOT_INIT_PATTERN) == -1) {
-					clearInterval(id)
-					return resolve({
-						docsify: docsify,
-						dom: dom
-					})
-				}
-			}, 10)
-		})
-		
-	})
-}
+