diff --git a/packages/vant-cli/site/common/iframe-router.js b/packages/vant-cli/site/common/iframe-router.js
index bdfba00f0..8f426e611 100644
--- a/packages/vant-cli/site/common/iframe-router.js
+++ b/packages/vant-cli/site/common/iframe-router.js
@@ -10,18 +10,18 @@ window.syncPath = function () {
   const currentDir = router.history.current.path;
 
   if (isInIframe) {
-    window.top.changePath(currentDir);
+    window.top.replacePath(currentDir);
   } else if (!isMobile) {
     const iframe = document.querySelector('iframe');
     if (iframe) {
       iframeReady(iframe, () => {
-        iframe.contentWindow.changePath(currentDir);
+        iframe.contentWindow.replacePath(currentDir);
       });
     }
   }
 };
 
-window.changePath = function (path = '') {
+window.replacePath = function (path = '') {
   // should preserve hash for anchor
   if (window.vueRouter.currentRoute.path !== path) {
     window.vueRouter.replace(path).catch(() => {});
diff --git a/packages/vant-cli/site/common/index.js b/packages/vant-cli/site/common/index.js
index 583d53634..7bc50e0eb 100644
--- a/packages/vant-cli/site/common/index.js
+++ b/packages/vant-cli/site/common/index.js
@@ -1,7 +1,7 @@
 function iframeReady(iframe, callback) {
   const doc = iframe.contentDocument || iframe.contentWindow.document;
   const interval = () => {
-    if (iframe.contentWindow.changePath) {
+    if (iframe.contentWindow.replacePath) {
       callback();
     } else {
       setTimeout(() => {
diff --git a/packages/vant-cli/site/desktop/App.vue b/packages/vant-cli/site/desktop/App.vue
index d27640470..1d05171a0 100644
--- a/packages/vant-cli/site/desktop/App.vue
+++ b/packages/vant-cli/site/desktop/App.vue
@@ -65,6 +65,23 @@ export default {
   watch: {
     lang(val) {
       setLang(val);
+      this.setTitle();
+    }
+  },
+
+  created() {
+    this.setTitle();
+  },
+
+  methods: {
+    setTitle() {
+      let { title } = this.config;
+
+      if (this.config.description) {
+        title += ` - ${this.config.description}`;
+      }
+
+      document.title = title;
     }
   }
 };
diff --git a/packages/vant-cli/site/desktop/components/Simulator.vue b/packages/vant-cli/site/desktop/components/Simulator.vue
index f66aa80dc..b51b1df4e 100644
--- a/packages/vant-cli/site/desktop/components/Simulator.vue
+++ b/packages/vant-cli/site/desktop/components/Simulator.vue
@@ -9,8 +9,7 @@ export default {
   name: 'van-doc-simulator',
 
   props: {
-    src: String,
-    lang: String
+    src: String
   },
 
   data() {
@@ -33,12 +32,6 @@ export default {
     }
   },
 
-  watch: {
-    lang(val) {
-      location.hash = `#${location.hash.replace(this.lang, val)}`;
-    }
-  },
-
   mounted() {
     window.addEventListener('scroll', () => {
       this.scrollTop = window.scrollY;
diff --git a/packages/vant-cli/site/desktop/components/index.vue b/packages/vant-cli/site/desktop/components/index.vue
index d849becb0..155e6bd04 100644
--- a/packages/vant-cli/site/desktop/components/index.vue
+++ b/packages/vant-cli/site/desktop/components/index.vue
@@ -13,7 +13,7 @@
         <slot />
       </doc-content>
     </doc-container>
-    <doc-simulator v-if="simulator" :src="simulator" :lang="lang" />
+    <doc-simulator v-if="simulator" :src="simulator" />
   </div>
 </template>
 
diff --git a/packages/vant-cli/site/desktop/router.js b/packages/vant-cli/site/desktop/router.js
index 24dc82d53..1e135179a 100644
--- a/packages/vant-cli/site/desktop/router.js
+++ b/packages/vant-cli/site/desktop/router.js
@@ -31,6 +31,17 @@ function parseName(name) {
   };
 }
 
+function getLangFromRoute(route) {
+  const lang = route.path.split('/')[1];
+  const langs = Object.keys(locales);
+
+  if (langs.indexOf(lang) !== -1) {
+    return lang;
+  }
+
+  return getLang();
+}
+
 function getRoutes() {
   const routes = [];
   const names = Object.keys(documents);
@@ -38,7 +49,7 @@ function getRoutes() {
   if (locales) {
     routes.push({
       path: '*',
-      redirect: `/${getLang()}/`
+      redirect: route => `/${getLangFromRoute(route)}/`
     });
   } else {
     routes.push({
diff --git a/packages/vant-cli/site/mobile/router.js b/packages/vant-cli/site/mobile/router.js
index dcb17ec5c..3635b782a 100644
--- a/packages/vant-cli/site/mobile/router.js
+++ b/packages/vant-cli/site/mobile/router.js
@@ -10,6 +10,17 @@ const { locales, defaultLang } = config.site;
 
 setDefaultLang(defaultLang);
 
+function getLangFromRoute(route) {
+  const lang = route.path.split('/')[1];
+  const langs = Object.keys(locales);
+
+  if (langs.indexOf(lang) !== -1) {
+    return lang;
+  }
+
+  return getLang();
+}
+
 function getRoutes() {
   const routes = [];
   const names = Object.keys(demos);
@@ -18,7 +29,7 @@ function getRoutes() {
   if (langs.length) {
     routes.push({
       path: '*',
-      redirect: () => `/${getLang()}/`
+      redirect: route => `/${getLangFromRoute(route)}/`
     });
 
     langs.forEach(lang => {
diff --git a/packages/vant-cli/src/compiler/gen-site-desktop-shared.ts b/packages/vant-cli/src/compiler/gen-site-desktop-shared.ts
index 48065c1e5..5bcde6458 100644
--- a/packages/vant-cli/src/compiler/gen-site-desktop-shared.ts
+++ b/packages/vant-cli/src/compiler/gen-site-desktop-shared.ts
@@ -1,11 +1,10 @@
 import glob from 'fast-glob';
 import { join, parse } from 'path';
-import { existsSync } from 'fs-extra';
+import { existsSync, readdirSync } from 'fs-extra';
 import {
   pascalize,
   removeExt,
   getVantConfig,
-  getComponents,
   smartOutputFile
 } from '../common';
 import {
@@ -96,8 +95,8 @@ function genExportConfig() {
 }
 
 export function genSiteDesktopShared() {
-  const components = getComponents();
-  const documents = resolveDocuments(components);
+  const dirs = readdirSync(SRC_DIR);
+  const documents = resolveDocuments(dirs);
 
   const code = `${genImportConfig()}
 ${genImportDocuments(documents)}
diff --git a/packages/vant-cli/src/compiler/gen-site-mobile-shared.ts b/packages/vant-cli/src/compiler/gen-site-mobile-shared.ts
index a0b2290bd..082e12643 100644
--- a/packages/vant-cli/src/compiler/gen-site-mobile-shared.ts
+++ b/packages/vant-cli/src/compiler/gen-site-mobile-shared.ts
@@ -1,12 +1,11 @@
 import { join } from 'path';
-import { existsSync } from 'fs-extra';
+import { existsSync, readdirSync } from 'fs-extra';
 import { SRC_DIR, SITE_MODILE_SHARED_FILE } from '../common/constant';
 import {
   pascalize,
   removeExt,
   decamelize,
   getVantConfig,
-  getComponents,
   smartOutputFile
 } from '../common';
 
@@ -90,8 +89,8 @@ ${genConfig(demos)}
 }
 
 export function genSiteMobileShared() {
-  const components = getComponents();
-  const code = genCode(components);
+  const dirs = readdirSync(SRC_DIR);
+  const code = genCode(dirs);
 
   smartOutputFile(SITE_MODILE_SHARED_FILE, code);
 }
diff --git a/packages/vant-cli/src/config/webpack.site.dev.ts b/packages/vant-cli/src/config/webpack.site.dev.ts
index ad9a0a153..aa7cfa4d9 100644
--- a/packages/vant-cli/src/config/webpack.site.dev.ts
+++ b/packages/vant-cli/src/config/webpack.site.dev.ts
@@ -9,8 +9,28 @@ import {
   SITE_DESKTOP_SHARED_FILE
 } from '../common/constant';
 
-const siteConfig = getVantConfig().site;
-const title = `${siteConfig.title} - ${siteConfig.description}`;
+function getSiteConfig() {
+  const siteConfig = getVantConfig().site;
+
+  if (siteConfig.locales) {
+    return siteConfig.locales[siteConfig.defaultLang || 'en-US'];
+  }
+
+  return siteConfig;
+}
+
+function getTitle(config: { title: string, description?: string }) {
+  let { title } = config;
+
+  if (config.description) {
+    title += ` - ${config.description}`;
+  }
+
+  return title;
+}
+
+const siteConfig = getSiteConfig();
+const title = getTitle(siteConfig);
 
 export const siteDevBaseConfig = merge(baseConfig as any, {
   entry: {