@xosen/site-sdk 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
<div class="x-nav__links" :class="{ 'x-nav__links--open': menuOpen }">
|
|
10
10
|
<template v-for="item in navigation" :key="item.url">
|
|
11
11
|
<a v-if="item.external" :href="item.url" class="x-nav__link" target="_blank" @click="menuOpen = false">
|
|
12
|
-
{{ item
|
|
12
|
+
{{ navText(item) }}
|
|
13
13
|
</a>
|
|
14
14
|
<router-link v-else :to="item.url" class="x-nav__link" @click="menuOpen = false">
|
|
15
|
-
{{ item
|
|
15
|
+
{{ navText(item) }}
|
|
16
16
|
</router-link>
|
|
17
17
|
</template>
|
|
18
18
|
|
|
@@ -30,11 +30,19 @@
|
|
|
30
30
|
|
|
31
31
|
<script setup lang="ts">
|
|
32
32
|
import { ref, onMounted, onUnmounted } from 'vue';
|
|
33
|
+
import { useI18n } from 'vue-i18n';
|
|
33
34
|
|
|
35
|
+
import type { NavItem } from '../../types/config.js';
|
|
34
36
|
import { useSiteConfig } from '../../composables/useSiteConfig.js';
|
|
35
37
|
import XLocaleSwitcher from '../common/XLocaleSwitcher.vue';
|
|
36
38
|
|
|
37
|
-
const {
|
|
39
|
+
const { locale } = useI18n();
|
|
40
|
+
const { navigation, branding, locales, defaultLocale } = useSiteConfig();
|
|
41
|
+
|
|
42
|
+
function navText(item: NavItem): string {
|
|
43
|
+
if (typeof item.text === 'string') return item.text;
|
|
44
|
+
return item.text[locale.value] || item.text[defaultLocale.value] || Object.values(item.text)[0] || '';
|
|
45
|
+
}
|
|
38
46
|
|
|
39
47
|
const scrolled = ref(false);
|
|
40
48
|
const menuOpen = ref(false);
|
|
@@ -54,10 +54,6 @@ export function useLivePreview() {
|
|
|
54
54
|
|
|
55
55
|
onMounted(() => {
|
|
56
56
|
window.addEventListener('message', handleMessage);
|
|
57
|
-
// Notify parent that preview is ready
|
|
58
|
-
if (isPreviewMode.value) {
|
|
59
|
-
window.parent.postMessage({ type: 'xosen-preview-ready' }, '*');
|
|
60
|
-
}
|
|
61
57
|
});
|
|
62
58
|
|
|
63
59
|
onUnmounted(() => {
|
|
@@ -9,6 +9,7 @@ export function useSiteConfig() {
|
|
|
9
9
|
const siteData = (window as any).__SITE_DATA__ as SiteData | undefined;
|
|
10
10
|
|
|
11
11
|
const config = computed<SiteConfig | null>(() => siteData?.config || null);
|
|
12
|
+
const components = computed<Record<string, any>>(() => (siteData as any)?.components || {});
|
|
12
13
|
|
|
13
14
|
const navigation = computed(() => config.value?.navigation || []);
|
|
14
15
|
const locales = computed(() => config.value?.locales || []);
|
|
@@ -26,6 +27,7 @@ export function useSiteConfig() {
|
|
|
26
27
|
|
|
27
28
|
return {
|
|
28
29
|
config,
|
|
30
|
+
components,
|
|
29
31
|
navigation,
|
|
30
32
|
locales,
|
|
31
33
|
defaultLocale,
|
package/src/types/config.ts
CHANGED
|
@@ -17,7 +17,7 @@ function detectLocale(request: Request, config: WorkerConfig): string {
|
|
|
17
17
|
return config.defaultLocale;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
function handleContentApi(url: URL, env: WorkerEnv): Promise<Response> | null {
|
|
20
|
+
function handleContentApi(url: URL, env: WorkerEnv, defaultLocale: string): Promise<Response> | null {
|
|
21
21
|
if (!url.pathname.startsWith('/api/content/')) return null;
|
|
22
22
|
|
|
23
23
|
const key = decodeURIComponent(url.pathname.replace('/api/content/', ''));
|
|
@@ -26,7 +26,16 @@ function handleContentApi(url: URL, env: WorkerEnv): Promise<Response> | null {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
return (async () => {
|
|
29
|
-
|
|
29
|
+
let value = await env.SITE_CONTENT.get(key);
|
|
30
|
+
|
|
31
|
+
// Fallback to default locale
|
|
32
|
+
if (!value) {
|
|
33
|
+
const lastColon = key.lastIndexOf(':');
|
|
34
|
+
if (lastColon > 0 && key.slice(lastColon + 1) !== defaultLocale) {
|
|
35
|
+
value = await env.SITE_CONTENT.get(key.slice(0, lastColon + 1) + defaultLocale);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
if (!value) {
|
|
31
40
|
return Response.json({ error: 'Not found' }, { status: 404 });
|
|
32
41
|
}
|
|
@@ -81,7 +90,7 @@ export function createSiteWorker(config: WorkerConfig): {
|
|
|
81
90
|
const url = new URL(request.url);
|
|
82
91
|
|
|
83
92
|
// API route: /api/content/:key
|
|
84
|
-
const apiResponse = handleContentApi(url, env);
|
|
93
|
+
const apiResponse = handleContentApi(url, env, config.defaultLocale);
|
|
85
94
|
if (apiResponse) return apiResponse;
|
|
86
95
|
|
|
87
96
|
// Static assets
|
|
@@ -95,6 +104,8 @@ export function createSiteWorker(config: WorkerConfig): {
|
|
|
95
104
|
const assetResponse = await env.ASSETS.fetch(new Request(indexUrl));
|
|
96
105
|
let html = await assetResponse.text();
|
|
97
106
|
|
|
107
|
+
const fallbackLocale = config.defaultLocale;
|
|
108
|
+
|
|
98
109
|
// Read 2 KV keys: config + content for locale
|
|
99
110
|
const [configRaw, contentRaw] = await Promise.all([
|
|
100
111
|
env.SITE_CONTENT.get('config'),
|
|
@@ -102,7 +113,13 @@ export function createSiteWorker(config: WorkerConfig): {
|
|
|
102
113
|
]);
|
|
103
114
|
|
|
104
115
|
const siteConfig = configRaw ? JSON.parse(configRaw) : {};
|
|
105
|
-
|
|
116
|
+
let content: Record<string, PageData> = contentRaw ? JSON.parse(contentRaw) : {};
|
|
117
|
+
|
|
118
|
+
// Fallback to default locale if no content for requested locale
|
|
119
|
+
if (!contentRaw && locale !== fallbackLocale) {
|
|
120
|
+
const fallbackRaw = await env.SITE_CONTENT.get(`content:${fallbackLocale}`);
|
|
121
|
+
if (fallbackRaw) content = JSON.parse(fallbackRaw);
|
|
122
|
+
}
|
|
106
123
|
|
|
107
124
|
const pageMatch = url.pathname.match(/^\/p\/(.+)$/);
|
|
108
125
|
|
|
@@ -110,7 +127,11 @@ export function createSiteWorker(config: WorkerConfig): {
|
|
|
110
127
|
if (pageMatch) {
|
|
111
128
|
const slug = pageMatch[1];
|
|
112
129
|
if (!content[slug]) {
|
|
113
|
-
|
|
130
|
+
let value = await env.SITE_CONTENT.get(`page:${slug}:${locale}`);
|
|
131
|
+
// Fallback to default locale
|
|
132
|
+
if (!value && locale !== fallbackLocale) {
|
|
133
|
+
value = await env.SITE_CONTENT.get(`page:${slug}:${fallbackLocale}`);
|
|
134
|
+
}
|
|
114
135
|
if (value) content[slug] = JSON.parse(value);
|
|
115
136
|
}
|
|
116
137
|
}
|