diff --git a/packages/@vuepress/markdown/__tests__/__snapshots__/snippet.spec.js.snap b/packages/@vuepress/markdown/__tests__/__snapshots__/snippet.spec.js.snap
index 6514898292..bae5b09699 100644
--- a/packages/@vuepress/markdown/__tests__/__snapshots__/snippet.spec.js.snap
+++ b/packages/@vuepress/markdown/__tests__/__snapshots__/snippet.spec.js.snap
@@ -17,6 +17,37 @@ exports[`snippet import snippet 1`] = `
 </code></pre>
 `;
 
+exports[`snippet import snippet with region and highlight 1`] = `
+<pre><code class="language-js{1,3}">function foo () {
+  return ({
+    dest: '../../vuepress',
+    locales: {
+      '/': {
+        lang: 'en-US',
+        title: 'VuePress',
+        description: 'Vue-powered Static Site Generator'
+      },
+      '/zh/': {
+        lang: 'zh-CN',
+        title: 'VuePress',
+        description: 'Vue 驱动的静态网站生成器'
+      }
+    },
+    head: [
+      ['link', { rel: 'icon', href: \`/logo.png\` }],
+      ['link', { rel: 'manifest', href: '/manifest.json' }],
+      ['meta', { name: 'theme-color', content: '#3eaf7c' }],
+      ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
+      ['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }],
+      ['link', { rel: 'apple-touch-icon', href: \`/icons/apple-touch-icon-152x152.png\` }],
+      ['link', { rel: 'mask-icon', href: '/icons/safari-pinned-tab.svg', color: '#3eaf7c' }],
+      ['meta', { name: 'msapplication-TileImage', content: '/icons/msapplication-icon-144x144.png' }],
+      ['meta', { name: 'msapplication-TileColor', content: '#000000' }]
+    ]
+  })
+}</code></pre>
+`;
+
 exports[`snippet import snippet with highlight multiple lines 1`] = `
 <div class="highlight-lines">
   <div class="highlighted">&nbsp;</div>
@@ -35,3 +66,72 @@ exports[`snippet import snippet with highlight single line 1`] = `
 // ..
 }
 `;
+
+exports[`snippet import snippet with indented region 1`] = `
+<pre><code class="language-html">&lt;section&gt;
+  &lt;h1&gt;Hello World&lt;/h1&gt;
+&lt;/section&gt;
+&lt;div&gt;Lorem Ipsum&lt;/div&gt;</code></pre>
+`;
+
+exports[`snippet import snippet with region 1`] = `
+<pre><code class="language-js">function foo () {
+  return ({
+    dest: '../../vuepress',
+    locales: {
+      '/': {
+        lang: 'en-US',
+        title: 'VuePress',
+        description: 'Vue-powered Static Site Generator'
+      },
+      '/zh/': {
+        lang: 'zh-CN',
+        title: 'VuePress',
+        description: 'Vue 驱动的静态网站生成器'
+      }
+    },
+    head: [
+      ['link', { rel: 'icon', href: \`/logo.png\` }],
+      ['link', { rel: 'manifest', href: '/manifest.json' }],
+      ['meta', { name: 'theme-color', content: '#3eaf7c' }],
+      ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
+      ['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }],
+      ['link', { rel: 'apple-touch-icon', href: \`/icons/apple-touch-icon-152x152.png\` }],
+      ['link', { rel: 'mask-icon', href: '/icons/safari-pinned-tab.svg', color: '#3eaf7c' }],
+      ['meta', { name: 'msapplication-TileImage', content: '/icons/msapplication-icon-144x144.png' }],
+      ['meta', { name: 'msapplication-TileColor', content: '#000000' }]
+    ]
+  })
+}</code></pre>
+`;
+
+exports[`snippet import snippet with region and single line highlight > 10 1`]  = `
+<pre><code class="language-js{11}">function foo () {
+  return ({
+    dest: '../../vuepress',
+    locales: {
+      '/': {
+        lang: 'en-US',
+        title: 'VuePress',
+        description: 'Vue-powered Static Site Generator'
+      },
+      '/zh/': {
+        lang: 'zh-CN',
+        title: 'VuePress',
+        description: 'Vue 驱动的静态网站生成器'
+      }
+    },
+    head: [
+      ['link', { rel: 'icon', href: \`/logo.png\` }],
+      ['link', { rel: 'manifest', href: '/manifest.json' }],
+      ['meta', { name: 'theme-color', content: '#3eaf7c' }],
+      ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
+      ['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }],
+      ['link', { rel: 'apple-touch-icon', href: \`/icons/apple-touch-icon-152x152.png\` }],
+      ['link', { rel: 'mask-icon', href: '/icons/safari-pinned-tab.svg', color: '#3eaf7c' }],
+      ['meta', { name: 'msapplication-TileImage', content: '/icons/msapplication-icon-144x144.png' }],
+      ['meta', { name: 'msapplication-TileColor', content: '#000000' }]
+    ]
+  })
+}</code></pre>
+`;
diff --git a/packages/@vuepress/markdown/__tests__/fragments/code-snippet-with-indented-region.md b/packages/@vuepress/markdown/__tests__/fragments/code-snippet-with-indented-region.md
new file mode 100644
index 0000000000..71e314122f
--- /dev/null
+++ b/packages/@vuepress/markdown/__tests__/fragments/code-snippet-with-indented-region.md
@@ -0,0 +1 @@
+<<< @/packages/@vuepress/markdown/__tests__/fragments/snippet-with-indented-region.html#body
diff --git a/packages/@vuepress/markdown/__tests__/fragments/code-snippet-with-region-and-highlight.md b/packages/@vuepress/markdown/__tests__/fragments/code-snippet-with-region-and-highlight.md
new file mode 100644
index 0000000000..45f13d6f05
--- /dev/null
+++ b/packages/@vuepress/markdown/__tests__/fragments/code-snippet-with-region-and-highlight.md
@@ -0,0 +1 @@
+<<< @/packages/@vuepress/markdown/__tests__/fragments/snippet-with-region.js#snippet{1,3}
diff --git a/packages/@vuepress/markdown/__tests__/fragments/code-snippet-with-region-and-single-highlight.md b/packages/@vuepress/markdown/__tests__/fragments/code-snippet-with-region-and-single-highlight.md
new file mode 100644
index 0000000000..c67cff011a
--- /dev/null
+++ b/packages/@vuepress/markdown/__tests__/fragments/code-snippet-with-region-and-single-highlight.md
@@ -0,0 +1 @@
+<<< @/packages/@vuepress/markdown/__tests__/fragments/snippet-with-region.js#snippet{11}
diff --git a/packages/@vuepress/markdown/__tests__/fragments/code-snippet-with-region.md b/packages/@vuepress/markdown/__tests__/fragments/code-snippet-with-region.md
new file mode 100644
index 0000000000..a335dbec46
--- /dev/null
+++ b/packages/@vuepress/markdown/__tests__/fragments/code-snippet-with-region.md
@@ -0,0 +1 @@
+<<< @/packages/@vuepress/markdown/__tests__/fragments/snippet-with-region.js#snippet
diff --git a/packages/@vuepress/markdown/__tests__/fragments/snippet-with-indented-region.html b/packages/@vuepress/markdown/__tests__/fragments/snippet-with-indented-region.html
new file mode 100644
index 0000000000..ff845c8ac5
--- /dev/null
+++ b/packages/@vuepress/markdown/__tests__/fragments/snippet-with-indented-region.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>Document</title>
+</head>
+<body>
+  <!-- #region body -->
+  <section>
+    <h1>Hello World</h1>
+  </section>
+  <div>Lorem Ipsum</div>
+  <!-- #endregion body -->
+</body>
+</html>
\ No newline at end of file
diff --git a/packages/@vuepress/markdown/__tests__/fragments/snippet-with-region.js b/packages/@vuepress/markdown/__tests__/fragments/snippet-with-region.js
new file mode 100644
index 0000000000..bacd171ddd
--- /dev/null
+++ b/packages/@vuepress/markdown/__tests__/fragments/snippet-with-region.js
@@ -0,0 +1,32 @@
+// #region snippet
+function foo () {
+  return ({
+    dest: '../../vuepress',
+    locales: {
+      '/': {
+        lang: 'en-US',
+        title: 'VuePress',
+        description: 'Vue-powered Static Site Generator'
+      },
+      '/zh/': {
+        lang: 'zh-CN',
+        title: 'VuePress',
+        description: 'Vue 驱动的静态网站生成器'
+      }
+    },
+    head: [
+      ['link', { rel: 'icon', href: `/logo.png` }],
+      ['link', { rel: 'manifest', href: '/manifest.json' }],
+      ['meta', { name: 'theme-color', content: '#3eaf7c' }],
+      ['meta', { name: 'apple-mobile-web-app-capable', content: 'yes' }],
+      ['meta', { name: 'apple-mobile-web-app-status-bar-style', content: 'black' }],
+      ['link', { rel: 'apple-touch-icon', href: `/icons/apple-touch-icon-152x152.png` }],
+      ['link', { rel: 'mask-icon', href: '/icons/safari-pinned-tab.svg', color: '#3eaf7c' }],
+      ['meta', { name: 'msapplication-TileImage', content: '/icons/msapplication-icon-144x144.png' }],
+      ['meta', { name: 'msapplication-TileColor', content: '#000000' }]
+    ]
+  })
+}
+// #endregion snippet
+
+export default foo
diff --git a/packages/@vuepress/markdown/__tests__/snippet.spec.js b/packages/@vuepress/markdown/__tests__/snippet.spec.js
index e8e25ea723..af018be673 100644
--- a/packages/@vuepress/markdown/__tests__/snippet.spec.js
+++ b/packages/@vuepress/markdown/__tests__/snippet.spec.js
@@ -30,4 +30,28 @@ describe('snippet', () => {
     const output = mdH.render(input)
     expect(output).toMatchSnapshot()
   })
+
+  test('import snippet with region', () => {
+    const input = getFragment(__dirname, 'code-snippet-with-region.md')
+    const output = md.render(input)
+    expect(output).toMatchSnapshot()
+  })
+
+  test('import snippet with region and highlight', () => {
+    const input = getFragment(__dirname, 'code-snippet-with-region-and-highlight.md')
+    const output = md.render(input)
+    expect(output).toMatchSnapshot()
+  })
+
+  test('import snippet with region and single line highlight > 10', () => {
+    const input = getFragment(__dirname, 'code-snippet-with-region-and-single-highlight.md')
+    const output = md.render(input)
+    expect(output).toMatchSnapshot()
+  })
+
+  test('import snippet with indented region', () => {
+    const input = getFragment(__dirname, 'code-snippet-with-indented-region.md')
+    const output = md.render(input)
+    expect(output).toMatchSnapshot()
+  })
 })
diff --git a/packages/@vuepress/markdown/lib/snippet.js b/packages/@vuepress/markdown/lib/snippet.js
index 9ee4e726f3..037498d336 100644
--- a/packages/@vuepress/markdown/lib/snippet.js
+++ b/packages/@vuepress/markdown/lib/snippet.js
@@ -1,5 +1,74 @@
 const { fs, logger, path } = require('@vuepress/shared-utils')
 
+function dedent (text) {
+  const wRegexp = /^([ \t]*)(.*)\n/gm
+  let match; let minIndentLength = null
+
+  while ((match = wRegexp.exec(text)) !== null) {
+    const [indentation, content] = match.slice(1)
+    if (!content) continue
+
+    const indentLength = indentation.length
+    if (indentLength > 0) {
+      minIndentLength
+        = minIndentLength !== null
+          ? Math.min(minIndentLength, indentLength)
+          : indentLength
+    } else break
+  }
+
+  if (minIndentLength) {
+    text = text.replace(
+      new RegExp(`^[ \t]{${minIndentLength}}(.*)`, 'gm'),
+      '$1'
+    )
+  }
+
+  return text
+}
+
+function testLine (line, regexp, regionName, end = false) {
+  const [full, tag, name] = regexp.exec(line.trim()) || []
+
+  return (
+    full
+    && tag
+    && name === regionName
+    && tag.match(end ? /^[Ee]nd ?[rR]egion$/ : /^[rR]egion$/)
+  )
+}
+
+function findRegion (lines, regionName) {
+  const regionRegexps = [
+    /^\/\/ ?#?((?:end)?region) ([\w*-]+)$/, // javascript, typescript, java
+    /^\/\* ?#((?:end)?region) ([\w*-]+) ?\*\/$/, // css, less, scss
+    /^#pragma ((?:end)?region) ([\w*-]+)$/, // C, C++
+    /^<!-- #?((?:end)?region) ([\w*-]+) -->$/, // HTML, markdown
+    /^#((?:End )Region) ([\w*-]+)$/, // Visual Basic
+    /^::#((?:end)region) ([\w*-]+)$/, // Bat
+    /^# ?((?:end)?region) ([\w*-]+)$/ // C#, PHP, Powershell, Python, perl & misc
+  ]
+
+  let regexp = null
+  let start = -1
+
+  for (const [lineId, line] of lines.entries()) {
+    if (regexp === null) {
+      for (const reg of regionRegexps) {
+        if (testLine(line, reg, regionName)) {
+          start = lineId + 1
+          regexp = reg
+          break
+        }
+      }
+    } else if (testLine(line, regexp, regionName, true)) {
+      return { start, end: lineId, regexp }
+    }
+  }
+
+  return null
+}
+
 module.exports = function snippet (md, options = {}) {
   const fence = md.renderer.rules.fence
   const root = options.root || process.cwd()
@@ -7,15 +76,32 @@ module.exports = function snippet (md, options = {}) {
   md.renderer.rules.fence = (...args) => {
     const [tokens, idx, , { loader }] = args
     const token = tokens[idx]
-    const { src } = token
+    const [src, regionName] = token.src ? token.src.split('#') : ['']
     if (src) {
       if (loader) {
         loader.addDependency(src)
       }
-      if (fs.existsSync(src)) {
-        token.content = fs.readFileSync(src, 'utf8')
+      const isAFile = fs.lstatSync(src).isFile()
+      if (fs.existsSync(src) && isAFile) {
+        let content = fs.readFileSync(src, 'utf8')
+
+        if (regionName) {
+          const lines = content.split(/\r?\n/)
+          const region = findRegion(lines, regionName)
+
+          if (region) {
+            content = dedent(
+              lines
+                .slice(region.start, region.end)
+                .filter(line => !region.regexp.test(line.trim()))
+                .join('\n')
+            )
+          }
+        }
+
+        token.content = content
       } else {
-        token.content = `Code snippet path not found: ${src}`
+        token.content = isAFile ? `Code snippet path not found: ${src}` : `Invalid code snippet option`
         token.info = ''
         logger.error(token.content)
       }
@@ -44,15 +130,23 @@ module.exports = function snippet (md, options = {}) {
 
     const start = pos + 3
     const end = state.skipSpacesBack(max, pos)
-    const rawPath = state.src.slice(start, end).trim().replace(/^@/, root)
-    const filename = rawPath.split(/{/).shift().trim()
-    const meta = rawPath.replace(filename, '')
+
+    /**
+     * raw path format: "/path/to/file.extension#region {meta}"
+     *    where #region and {meta} are optionnal
+     *
+     * captures: ['/path/to/file.extension', 'extension', '#region', '{meta}']
+     */
+    const rawPathRegexp = /^(.+(?:\.([a-z]+)))(?:(#[\w-]+))?(?: ?({\d+(?:[,-]\d+)?}))?$/
+
+    const rawPath = state.src.slice(start, end).trim().replace(/^@/, root).trim()
+    const [filename = '', extension = '', region = '', meta = ''] = (rawPathRegexp.exec(rawPath) || []).slice(1)
 
     state.line = startLine + 1
 
     const token = state.push('fence', 'code', 0)
-    token.info = filename.split('.').pop() + meta
-    token.src = path.resolve(filename)
+    token.info = extension + meta
+    token.src = path.resolve(filename) + region
     token.markup = '```'
     token.map = [startLine, startLine + 1]
 
diff --git a/packages/docs/docs/guide/markdown.md b/packages/docs/docs/guide/markdown.md
index af2a7f13bc..41403951aa 100644
--- a/packages/docs/docs/guide/markdown.md
+++ b/packages/docs/docs/guide/markdown.md
@@ -345,6 +345,29 @@ It also supports [line highlighting](#line-highlighting-in-code-blocks):
 Since the import of the code snippets will be executed before webpack compilation, you can’t use the path alias in webpack. The default value of `@` is `process.cwd()`.
 :::
 
+You can also use a [VS Code region](https://code.visualstudio.com/docs/editor/codebasics#_folding) in order to only include the corresponding part of the code file. You can provide a custom region name after a `#` following the filepath (`snippet` by default).
+
+**Input**
+
+``` md
+<<< @/../@vuepress/markdown/__tests__/fragments/snippet-with-region.js#snippet{1}
+```
+
+**Code file**
+
+<!--lint disable strong-marker-->
+
+<<< @/../@vuepress/markdown/__tests__/fragments/snippet-with-region.js
+
+<!--lint enable strong-marker-->
+
+**Output**
+
+<!--lint disable strong-marker-->
+
+<<< @/../@vuepress/markdown/__tests__/fragments/snippet-with-region.js#snippet{1}
+
+<!--lint enable strong-marker-->
 
 ## Advanced Configuration