diff --git a/docs/.vitepress/theme/SodesuComment.vue b/docs/.vitepress/theme/SodesuComment.vue
index 5b32f93..370d8ad 100644
--- a/docs/.vitepress/theme/SodesuComment.vue
+++ b/docs/.vitepress/theme/SodesuComment.vue
@@ -14,16 +14,22 @@
   </div>
 </template>
 
-<script setup>
-import { onMounted } from 'vue';
+<script setup lang="ts">
+import { useRoute } from 'vitepress';
+import { onMounted, ref, watch } from 'vue';
+
 import '../../../dist/sodesu-comment.css';
 
+const route = useRoute();
+
+const sodesu = ref<ReturnType<(typeof import('../../../src/index'))['init']> | null>(null);
+
 onMounted(async () => {
   const [Sodesu, remarkRenderer] = await Promise.all([
     import('../../../dist/sodesu.aio.mjs'),
     import('../../../src/utils/remarkRenderer'),
   ]);
-  Sodesu.default.init({
+  sodesu.value = Sodesu.init({
     el: '#sodesu-comment',
     serverURL: 'https://walinejs.comment.lithub.cc',
     dark: 'html.dark',
@@ -31,6 +37,14 @@ onMounted(async () => {
     renderPreview: remarkRenderer.default,
   });
 });
+
+watch(
+  () => route.path,
+  async () => {
+    sodesu.value?.update({ path: route.path });
+  },
+  { immediate: true },
+);
 </script>
 
 <style scoped>
diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts
index 925872c..dc7fe1e 100644
--- a/docs/.vitepress/theme/index.ts
+++ b/docs/.vitepress/theme/index.ts
@@ -2,18 +2,9 @@ import DefaultTheme from 'vitepress/theme';
 import SodesuLayout from './SodesuLayout.vue';
 import 'katex/dist/katex.min.css';
 
-const theme: typeof DefaultTheme = {
+const theme = {
   ...DefaultTheme,
   Layout: SodesuLayout,
-  enhanceApp: (ctx) => {
-    DefaultTheme.enhanceApp(ctx);
-    if (typeof window !== 'undefined') {
-      ctx.router.onAfterRouteChanged = async (to) => {
-        const Sodesu = await import('../../../dist/sodesu.aio.mjs');
-        Sodesu.default.update({ path: window.location.pathname });
-      };
-    }
-  },
 };
 
 export default theme;
diff --git a/docs/guide/getting-started.md b/docs/guide/getting-started.md
index dace3f2..be7b436 100644
--- a/docs/guide/getting-started.md
+++ b/docs/guide/getting-started.md
@@ -48,9 +48,9 @@ pnpm add sodesu-comment
 
 如果你的项目中已经存在 Solid.js,那么你可以引入不含 Solid.js 的 Sodesu,这可以让你的 JS 体积小十几 kB。
 
-```js
-import Sodesu from 'sodesu';
-Sodesu.init({
+```ts
+import { init } from 'sodesu-comment';
+init({
   el: '#sodesu',
   serverURL: 'https://your-domain.vercel.app',
 });
@@ -64,9 +64,9 @@ pnpm add solid-js
 
 当然,你也可以选择引入已经包含了 Solid.js 的 Sodesu:
 
-```js
-import Sodesu from 'sodesu/aio';
-Sodesu.init({
+```ts
+import { init } from 'sodesu-comment/aio';
+init({
   el: '#sodesu',
   serverURL: 'https://your-domain.vercel.app',
 });
@@ -74,13 +74,13 @@ Sodesu.init({
 
 无论是哪一种方式,都没有引入样式。所以你可以参考 CDN 引入时的办法,在 html 中引入它。但如果你的项目足够工程化,那么你可以直接在你的页面中引入样式:
 
-```js
+```ts
 import 'sodesu-comment/sodesu-comment.css';
 ```
 
 或者,如果你的项目已经在使用 UnoCSS,那么你可以将它配置一下:
 
-```js
+```ts
 import presetSodesu from 'sodesu-comment/preset';
 import safeList from 'sodesu-comment/safeList';
 import { defineConfig, presetWind } from 'unocss';
@@ -95,7 +95,7 @@ export default defineConfig({
 
 如果你用的不是 Astro,那么你或许可以使用类似这样的配置,只要确保 `include` 能覆盖到位于 `node_modules` 里的 `sodesu` 源码就可以了:
 
-```js
+```ts
 import presetSodesu from 'sodesu-comment/preset';
 import { defineConfig, presetWind } from 'unocss';
 
@@ -107,12 +107,33 @@ export default defineConfig({
 
 ## 单页应用支持
 
+`init` 函数会返回一个对象,你可以将其视作 Sodesu 的实例。其中包含两个方法,分别是 `update` 和 `destroy`。
+
 通过如下方式来对 Sodesu 的配置项进行更新:
 
-```js
-Sodesu.update({
-  /* Options */
+```ts{7-10}
+import { init } from 'sodesu-comment/aio';
+const sodesu = init({
+  el: '#sodesu',
+  serverURL: 'https://your-domain.vercel.app',
+});
+
+sodesu.update({
+  path: '/new-path',
+  /* any other options here */
+});
+```
+
+通过如下方式来销毁 Sodesu 实例:
+
+```ts{7}
+import { init } from 'sodesu-comment/aio';
+const sodesu = init({
+  el: '#sodesu',
+  serverURL: 'https://your-domain.vercel.app',
 });
+
+sodesu.destroy();
 ```
 
 ## 效果预览
diff --git a/docs/trade-offs.md b/docs/trade-offs.md
index 1d74747..be24885 100644
--- a/docs/trade-offs.md
+++ b/docs/trade-offs.md
@@ -77,6 +77,4 @@ Sodesu 会在评论区右下角显示一行类似这样的版权信息:
 
 <p class="py-1 text-sLightGrey text-info">Powered by Sodesu v1.1.4-alpha.514</p>
 
-与 Waline 的页脚版权信息可以开关不同,Sodesu 的页脚版权信息是强制开启的。这是因为 Sodesu 使用了 AGPL-3.0 协议 ~~(为什么?因为我喜欢)~~ ,这要求它的源码随服务一同分发。而如果把这个任务交给博客主,那么他们将需要经过比较复杂的配置才能做到这一点,因此 Sodesu 的页脚版权信息将强制开启,以确保源码(以链接的形式)与服务一并分发。
-
-据观察,关闭了 Waline 页脚版权信息的博客并不多。而对 Sodesu 用户来说,插入上面的版权信息,可以避免自己的整个博客都被 AGPL 协议“传染”着要求开源。在我看来这是一笔划算的交易。
+与 Waline 的页脚版权信息可以开关不同,Sodesu 的页脚版权信息是强制开启的。这是因为 Sodesu 使用了 AGPL-3.0 协议,这要求它的源码随服务(换言之,网页)一同分发。而如果把这个任务交给博客主,那么他们将需要经过比较复杂的配置才能做到这一点,因此 Sodesu 的页脚版权信息将强制开启,以确保源码(以链接的形式)与服务一并分发。
diff --git a/index.html b/index.html
index ec3d1f4..d0e2cd1 100644
--- a/index.html
+++ b/index.html
@@ -15,10 +15,10 @@
     2:<span class="waline-pageview-count" data-path="/guide/features/i18n.html"></span>
     <div id="root"></div>
     <script type="module">
-      import Sodesu from '/src/index.tsx';
+      import { init } from '/src/index.tsx';
       import remarkRenderer from '/src/utils/remarkRenderer.ts';
       import 'virtual:uno.css';
-      Sodesu.init({
+      init({
         el: '#root',
         serverURL: 'https://walinejs.comment.lithub.cc',
         dark: 'auto',
diff --git a/src/components/CommentCard.tsx b/src/components/CommentCard.tsx
index 28a56c1..dffa72a 100644
--- a/src/components/CommentCard.tsx
+++ b/src/components/CommentCard.tsx
@@ -27,7 +27,6 @@ const CommentCard: Component<{ content: ReactiveComment; rootId: string }> = (pr
     <div id={props.content.objectId} class="flex p-2 pe-0 sds-comment">
       <div aria-hidden class="relative me-3 flex-shrink-0">
         <Show when={props.content.avatar}>
-          {/* 不加空格会被编译成 class=sds-avatar,怪 */}
           <img class="sds-avatar" src={props.content.avatar} alt={props.content.nick} />
           <Show when={props.content.type}>
             <VerifiedIcon />
diff --git a/src/controllers/configProvider.ts b/src/controllers/configProvider.ts
index c91ffcc..59dd9b3 100644
--- a/src/controllers/configProvider.ts
+++ b/src/controllers/configProvider.ts
@@ -57,10 +57,6 @@ const configProvider = createRoot(() => {
       });
     }
   };
-  onMount(() => {
-    mountPageView();
-    mountComment();
-  });
   createEffect(() => {
     mountPageView();
   });
diff --git a/src/index.tsx b/src/index.tsx
index fed383c..70fc9ea 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -4,18 +4,16 @@ import App from './App';
 import configProvider from './controllers/configProvider';
 import 'virtual:uno.css';
 
-const Sodesu = {
-  root: undefined as HTMLElement | undefined,
-  init: (opt: SodesuInitOptions) => {
-    Sodesu.root = configProvider.init(opt);
-    render(() => <App />, Sodesu.root!);
-  },
-  update: (opt: Partial<Omit<SodesuInitOptions, 'el'>>) => {
-    configProvider.update(opt);
-  },
-  destroy: () => {
-    if (Sodesu.root) Sodesu.root.innerHTML = '';
-  },
-};
+export const init = (opt: SodesuInitOptions) => {
+  const root = configProvider.init(opt);
+  render(() => <App />, root);
 
-export default Sodesu;
+  return {
+    update: (opt: Partial<Omit<SodesuInitOptions, 'el'>>) => {
+      configProvider.update(opt);
+    },
+    destroy: () => {
+      root.innerHTML = '';
+    },
+  };
+};