diff --git a/bun.lockb b/bun.lockb
index d7be6da..456dbfa 100644
Binary files a/bun.lockb and b/bun.lockb differ
diff --git a/components.d.ts b/components.d.ts
new file mode 100644
index 0000000..eb6c0af
--- /dev/null
+++ b/components.d.ts
@@ -0,0 +1,17 @@
+/* eslint-disable */
+// @ts-nocheck
+// Generated by unplugin-vue-components
+// Read more: https://github.com/vuejs/core/pull/3399
+// biome-ignore lint: disable
+export {}
+
+/* prettier-ignore */
+declare module 'vue' {
+ export interface GlobalComponents {
+ ClientOnly: typeof import('./src/components/ClientOnly.tsx')['default']
+ CookieDemo: typeof import('./src/components/CookieDemo.vue')['default']
+ DataFetch: typeof import('./src/components/DataFetch.vue')['default']
+ HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
+ SimpleTest: typeof import('./src/components/SimpleTest.vue')['default']
+ }
+}
diff --git a/package.json b/package.json
index 71ea955..abf2fec 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,9 @@
{
"name": "koa-ssr",
"type": "module",
+ "workspaces": [
+ "packages/*"
+ ],
"scripts": {
"dev": "bun run --watch server.ts",
"build": "npm run build:client && npm run build:server",
@@ -14,6 +17,7 @@
"@types/koa": "^3.0.0",
"@types/koa-send": "^4.1.6",
"cross-env": "^10.1.0",
+ "unplugin-vue-components": "^29.1.0",
"vue-tsc": "^3.1.0"
},
"peerDependencies": {
@@ -27,4 +31,4 @@
"vite": "^7.1.7",
"vue": "^3.5.22"
}
-}
\ No newline at end of file
+}
diff --git a/src/App.vue b/src/App.vue
index 6d00c7e..8433d2a 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -16,6 +16,9 @@ import SimpleTest from './components/SimpleTest.vue';
+
+ Only For Client
+
diff --git a/src/components/ClientOnly.tsx b/src/components/ClientOnly.tsx
new file mode 100644
index 0000000..fa64ae8
--- /dev/null
+++ b/src/components/ClientOnly.tsx
@@ -0,0 +1,43 @@
+import { cloneVNode, createElementBlock, defineComponent, getCurrentInstance, h, InjectionKey, onMounted, provide, shallowRef, SlotsType, VNode } from "vue";
+
+export const clientOnlySymbol: InjectionKey = Symbol.for('nuxt:client-only')
+
+export default defineComponent({
+ name: "ClientOnly",
+ inheritAttrs: false,
+ props: ['fallback', 'placeholder', 'placeholderTag', 'fallbackTag'],
+ ...(import.meta.env.DEV && {
+ slots: Object as SlotsType<{
+ default?: () => VNode[]
+
+ /**
+ * Specify a content to be rendered on the server and displayed until `` is mounted in the browser.
+ */
+ fallback?: () => VNode[]
+ placeholder?: () => VNode[]
+ }>,
+ }),
+ setup(props, { slots, attrs }) {
+ const mounted = shallowRef(false)
+ onMounted(() => { mounted.value = true })
+ const vm = getCurrentInstance()
+ if (vm) {
+ vm._nuxtClientOnly = true
+ }
+ provide(clientOnlySymbol, true)
+ return () => {
+ if (mounted.value) {
+ const vnodes = slots.default?.()
+ if (vnodes && vnodes.length === 1) {
+ return [cloneVNode(vnodes[0]!, attrs)]
+ }
+ return vnodes
+ }
+ const slot = slots.fallback || slots.placeholder
+ if (slot) { return h(slot) }
+ const fallbackStr = props.fallback || props.placeholder || ''
+ const fallbackTag = props.fallbackTag || props.placeholderTag || 'span'
+ return createElementBlock(fallbackTag, attrs, fallbackStr)
+ }
+ }
+})
diff --git a/src/components/CookieDemo.vue b/src/components/CookieDemo.vue
index 8d5ed24..69320a6 100644
--- a/src/components/CookieDemo.vue
+++ b/src/components/CookieDemo.vue
@@ -3,6 +3,9 @@
+
+ fuck ypu
+
服务端首屏会尝试设置缺失的 HttpOnly cookie,客户端不可读。
@@ -10,7 +13,8 @@