minhnt-dev: oonly ssr fix
This commit is contained in:
@@ -26,9 +26,7 @@ useHead({
|
|||||||
<div>
|
<div>
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
<NuxtLoadingIndicator />
|
<NuxtLoadingIndicator />
|
||||||
<ErrorBoundary>
|
<NuxtErrorBoundary>
|
||||||
|
|
||||||
|
|
||||||
<template #error="{ error }">
|
<template #error="{ error }">
|
||||||
<div class="text-center my-8">
|
<div class="text-center my-8">
|
||||||
<h2 class="mb-2">404</h2>
|
<h2 class="mb-2">404</h2>
|
||||||
@@ -38,14 +36,28 @@ useHead({
|
|||||||
trang chủ</button>
|
trang chủ</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</ErrorBoundary>
|
</NuxtErrorBoundary>
|
||||||
<ScrollToTop />
|
<KeepAlive>
|
||||||
|
<NuxtPage />
|
||||||
|
</KeepAlive>
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
</div>
|
</div>
|
||||||
</a-config-provider> -->
|
</a-config-provider> -->
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
<KeepAlive>
|
<NuxtLoadingIndicator />
|
||||||
<NuxtPage />
|
<NuxtErrorBoundary>
|
||||||
</KeepAlive>
|
<template #error="{ error }">
|
||||||
</NuxtLayout>
|
<div class="text-center my-8">
|
||||||
|
<h2 class="mb-2">404</h2>
|
||||||
|
<p class="mb-3">Trang không tồn tại.</p>
|
||||||
|
<p v-if="utils.isDev()">{{ error }}</p>
|
||||||
|
<button @click="resolveError(error)" type="button" class=" p-2 border focus:outline-none border-blue text-blue-7 hover:(bg-blue text-white) rounded-lg transition-colors">Về
|
||||||
|
trang chủ</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</NuxtErrorBoundary>
|
||||||
|
<KeepAlive>
|
||||||
|
<NuxtPage />
|
||||||
|
</KeepAlive>
|
||||||
|
</NuxtLayout>
|
||||||
</template>
|
</template>
|
||||||
+2
-4
@@ -3,12 +3,12 @@ const { resolve } = createResolver(import.meta.url);
|
|||||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
|
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
|
devtools: { enabled: true },
|
||||||
|
|
||||||
nitro: {
|
nitro: {
|
||||||
preset: 'iis_node'
|
preset: 'iis_node'
|
||||||
},
|
},
|
||||||
|
|
||||||
devtools: { enabled: true },
|
|
||||||
|
|
||||||
app: {
|
app: {
|
||||||
head: {
|
head: {
|
||||||
link: [],
|
link: [],
|
||||||
@@ -67,10 +67,8 @@ export default defineNuxtConfig({
|
|||||||
propsDestructure: true,
|
propsDestructure: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
target: 'server',
|
|
||||||
ssr: true,
|
ssr: true,
|
||||||
routeRules: {
|
routeRules: {
|
||||||
// Tất cả các route sẽ sử dụng SSR
|
|
||||||
'**': { ssr: true },
|
'**': { ssr: true },
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -2,18 +2,21 @@
|
|||||||
import DynamicTemplate from "~/components/dynamic-page/page/templates/index.vue";
|
import DynamicTemplate from "~/components/dynamic-page/page/templates/index.vue";
|
||||||
import DynamicSection from "~/components/dynamic-page/page-section/templates/index.vue";
|
import DynamicSection from "~/components/dynamic-page/page-section/templates/index.vue";
|
||||||
import { useDynamicPageStore } from '~/stores/dynamic-page';
|
import { useDynamicPageStore } from '~/stores/dynamic-page';
|
||||||
const { currentPage, sectionPublished, componentPublished } = storeToRefs(useDynamicPageStore());
|
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const store = reactive({
|
const store = reactive({
|
||||||
dynamicPage: useDynamicPageStore(),
|
dynamicPage: useDynamicPageStore(),
|
||||||
});
|
});
|
||||||
|
|
||||||
await useAsyncData('index', () => store.dynamicPage.fetchPageByCode(route.path.replace('/', '')))
|
const { data } = await useAsyncData('index', () => store.dynamicPage.fetchPageByCode(route.path.replace('/', '')))
|
||||||
|
const asycnCurrentPage = data.value.currentPage;
|
||||||
|
const asycnSectionPublished = data.value.sectionPublished;
|
||||||
|
const asycnComponentPublished = data.value.componentPublished;
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
title: () => currentPage.value.title || '',
|
title: () => asycnCurrentPage.title || '',
|
||||||
description: () => 'Với công nghệ đột phá và giải pháp sáng tạo, Vpress sẽ là đối tác tin cậy của các tòa soạn báo, cùng nhau kiến tạo nên những giá trị bền vững trong kỷ nguyên chuyển đổi số báo chí.',
|
description: () => 'Với công nghệ đột phá và giải pháp sáng tạo, Vpress sẽ là đối tác tin cậy của các tòa soạn báo, cùng nhau kiến tạo nên những giá trị bền vững trong kỷ nguyên chuyển đổi số báo chí.',
|
||||||
ogTitle: () => currentPage.value.title || '',
|
ogTitle: () => asycnCurrentPage.title || '',
|
||||||
ogImage: () => '~/assets/images/thumbnail.jpg',
|
ogImage: () => '~/assets/images/thumbnail.jpg',
|
||||||
ogDescription: () => 'Với công nghệ đột phá và giải pháp sáng tạo, Vpress sẽ là đối tác tin cậy của các tòa soạn báo, cùng nhau kiến tạo nên những giá trị bền vững trong kỷ nguyên chuyển đổi số báo chí.',
|
ogDescription: () => 'Với công nghệ đột phá và giải pháp sáng tạo, Vpress sẽ là đối tác tin cậy của các tòa soạn báo, cùng nhau kiến tạo nên những giá trị bền vững trong kỷ nguyên chuyển đổi số báo chí.',
|
||||||
twitterCard: () => 'summary_large_image',
|
twitterCard: () => 'summary_large_image',
|
||||||
@@ -21,10 +24,10 @@ useHead({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main class="h-screen" v-if="currentPage">
|
<main class="h-screen" v-if="asycnCurrentPage">
|
||||||
<DynamicTemplate :settings="currentPage.settings">
|
<DynamicTemplate :settings="asycnCurrentPage.settings">
|
||||||
<DynamicSection
|
<DynamicSection
|
||||||
v-for="(section, index) in sectionPublished"
|
v-for="(section, index) in asycnSectionPublished"
|
||||||
:key="index"
|
:key="index"
|
||||||
:settings="section.settings"
|
:settings="section.settings"
|
||||||
:content="section.content ? JSON.parse(section.content) : null"
|
:content="section.content ? JSON.parse(section.content) : null"
|
||||||
@@ -32,4 +35,4 @@ useHead({
|
|||||||
/>
|
/>
|
||||||
</DynamicTemplate>
|
</DynamicTemplate>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
+28
-24
@@ -10,22 +10,18 @@ import DynamicSection from "~/components/dynamic-page/page-section/templates/ind
|
|||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
import { useDynamicPageStore } from '~/stores/dynamic-page';
|
|
||||||
import { useArticleStore } from '~/stores/articles';
|
|
||||||
const { currentPage, sectionPublished, componentPublished } = storeToRefs(useDynamicPageStore());
|
|
||||||
const { currentArticle } = storeToRefs(useArticleStore());
|
|
||||||
|
|
||||||
const store = reactive({
|
const store = reactive({
|
||||||
dynamicPage: useDynamicPageStore(),
|
dynamicPage: useDynamicPageStore(),
|
||||||
article: useArticleStore(),
|
article: useArticleStore(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const loadPage = async () => {
|
import { useDynamicPageStore } from '~/stores/dynamic-page';
|
||||||
const promises = [];
|
import { useArticleStore } from '~/stores/articles';
|
||||||
promises.push(store.article.getArticleBySlug(route.params.slug));
|
|
||||||
|
|
||||||
|
const loadPage = async () => {
|
||||||
|
const article = await store.article.getArticleBySlug(route.params.slug);
|
||||||
let isContentType = '';
|
let isContentType = '';
|
||||||
switch (currentArticle.value?.contentType) {
|
switch (article.value?.contentType) {
|
||||||
case 1:
|
case 1:
|
||||||
isContentType = 'trang-chi-tiet-bai-viet-general';
|
isContentType = 'trang-chi-tiet-bai-viet-general';
|
||||||
break;
|
break;
|
||||||
@@ -39,11 +35,11 @@ const loadPage = async () => {
|
|||||||
isContentType = 'trang-chi-tiet-bai-viet-video';
|
isContentType = 'trang-chi-tiet-bai-viet-video';
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (currentArticle.value?.layoutType === 4) {
|
if (article.value?.layoutType === 4) {
|
||||||
isContentType = 'trang-chi-tiet-bai-viet-emagazine';
|
isContentType = 'trang-chi-tiet-bai-viet-emagazine';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (currentArticle.value?.layoutType === 3) {
|
if (article.value?.layoutType === 3) {
|
||||||
isContentType = 'trang-chi-tiet-bai-viet-infographics';
|
isContentType = 'trang-chi-tiet-bai-viet-infographics';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -51,34 +47,42 @@ const loadPage = async () => {
|
|||||||
isContentType = 'trang-chi-tiet-bai-viet-general';
|
isContentType = 'trang-chi-tiet-bai-viet-general';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
promises.push(store.dynamicPage.fetchPageByCode(isContentType));
|
const dynamicPage = await store.dynamicPage.fetchPageByCode(isContentType);
|
||||||
await Promise.all(promises);
|
|
||||||
|
return {
|
||||||
|
article,
|
||||||
|
dynamicPage
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
await useAsyncData('detail-article', () => loadPage());
|
const { data } = await useAsyncData('detail-article', () => loadPage());
|
||||||
|
const article = data.value?.article;
|
||||||
|
const dynamicPage = data.value?.dynamicPage;
|
||||||
|
|
||||||
|
const asycnCurrentPage = dynamicPage.currentPage;
|
||||||
|
const asycnSectionPublished = dynamicPage.sectionPublished;
|
||||||
|
const asycnComponentPublished = dynamicPage.componentPublished;
|
||||||
|
|
||||||
useSeoMeta({
|
useSeoMeta({
|
||||||
title: () => currentArticle.value.title.replace(/<[^>]+>/g, ''),
|
title: () => article.title.replace(/<[^>]+>/g, ''),
|
||||||
description: () => currentArticle.value.intro.replace(/<[^>]+>/g, ''),
|
description: () => article.intro.replace(/<[^>]+>/g, ''),
|
||||||
ogTitle: () => currentArticle.value.title.replace(/<[^>]+>/g, ''),
|
ogTitle: () => article.title.replace(/<[^>]+>/g, ''),
|
||||||
ogImage: () => currentArticle.value.thumbnail,
|
ogImage: () => article.thumbnail,
|
||||||
ogDescription: () => currentArticle.value.intro.replace(/<[^>]+>/g, ''),
|
ogDescription: () => article.intro.replace(/<[^>]+>/g, ''),
|
||||||
twitterCard: () => 'summary_large_image',
|
twitterCard: () => 'summary_large_image',
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main class="h-screen" v-if="currentPage && currentPage.settings">
|
<main class="h-screen" v-if="asycnCurrentPage">
|
||||||
<DynamicTemplate :settings="currentPage.settings">
|
<DynamicTemplate :settings="asycnCurrentPage.settings">
|
||||||
<template v-if="sectionPublished && sectionPublished.length > 0">
|
|
||||||
<DynamicSection
|
<DynamicSection
|
||||||
v-for="(section, index) in sectionPublished"
|
v-for="(section, index) in asycnSectionPublished"
|
||||||
:key="index"
|
:key="index"
|
||||||
:settings="section.settings"
|
:settings="section.settings"
|
||||||
:content="section.content ? JSON.parse(section.content) : null"
|
:content="section.content ? JSON.parse(section.content) : null"
|
||||||
:section="section"
|
:section="section"
|
||||||
/>
|
/>
|
||||||
</template>
|
|
||||||
</DynamicTemplate>
|
</DynamicTemplate>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
+8
-5
@@ -3,14 +3,17 @@ import ADSDefault from '@/assets/images/ads.jpg'
|
|||||||
import DynamicTemplate from "~/components/dynamic-page/page/templates/index.vue";
|
import DynamicTemplate from "~/components/dynamic-page/page/templates/index.vue";
|
||||||
import DynamicSection from "~/components/dynamic-page/page-section/templates/index.vue";
|
import DynamicSection from "~/components/dynamic-page/page-section/templates/index.vue";
|
||||||
import { useDynamicPageStore } from '~/stores/dynamic-page';
|
import { useDynamicPageStore } from '~/stores/dynamic-page';
|
||||||
const { currentPage, sectionPublished, componentPublished } = storeToRefs(useDynamicPageStore());
|
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const store = reactive({
|
const store = reactive({
|
||||||
dynamicPage: useDynamicPageStore(),
|
dynamicPage: useDynamicPageStore(),
|
||||||
});
|
});
|
||||||
|
|
||||||
await useAsyncData('index', () => store.dynamicPage.fetchPageByCode(route.path === '/' ? 'trang-chu' : route.path.replace('/', '')))
|
const { data } = await useAsyncData('index', () => store.dynamicPage.fetchPageByCode(route.path === '/' ? 'trang-chu' : route.path.replace('/', '')))
|
||||||
|
const asycnCurrentPage = data.value.currentPage;
|
||||||
|
const asycnSectionPublished = data.value.sectionPublished;
|
||||||
|
const asycnComponentPublished = data.value.componentPublished;
|
||||||
|
|
||||||
useHead({
|
useHead({
|
||||||
title: () => 'Trang chủ',
|
title: () => 'Trang chủ',
|
||||||
description: () => 'Với công nghệ đột phá và giải pháp sáng tạo, Vpress sẽ là đối tác tin cậy của các tòa soạn báo, cùng nhau kiến tạo nên những giá trị bền vững trong kỷ nguyên chuyển đổi số báo chí.',
|
description: () => 'Với công nghệ đột phá và giải pháp sáng tạo, Vpress sẽ là đối tác tin cậy của các tòa soạn báo, cùng nhau kiến tạo nên những giá trị bền vững trong kỷ nguyên chuyển đổi số báo chí.',
|
||||||
@@ -22,10 +25,10 @@ useHead({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main class="h-screen" v-if="currentPage">
|
<main class="h-screen" v-if="asycnCurrentPage">
|
||||||
<DynamicTemplate :settings="currentPage.settings">
|
<DynamicTemplate :settings="asycnCurrentPage.settings">
|
||||||
<DynamicSection
|
<DynamicSection
|
||||||
v-for="(section, index) in sectionPublished"
|
v-for="(section, index) in asycnSectionPublished"
|
||||||
:key="index"
|
:key="index"
|
||||||
:settings="section.settings"
|
:settings="section.settings"
|
||||||
:content="section.content ? JSON.parse(section.content) : null"
|
:content="section.content ? JSON.parse(section.content) : null"
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ export const useArticleStore = defineStore("article", () => {
|
|||||||
const article = await $fetch(`/api/articles/get-by-slug/${slug}`)
|
const article = await $fetch(`/api/articles/get-by-slug/${slug}`)
|
||||||
currentArticle.value = {}
|
currentArticle.value = {}
|
||||||
currentArticle.value = article?.item
|
currentArticle.value = article?.item
|
||||||
|
|
||||||
|
return currentArticle;
|
||||||
} catch (error: any) { }
|
} catch (error: any) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-22
@@ -4,27 +4,6 @@ export const useDynamicPageStore = defineStore("dynamicPageStore", () => {
|
|||||||
const currentPage = ref<any>({});
|
const currentPage = ref<any>({});
|
||||||
const sectionPublished = ref<any[]>([]);
|
const sectionPublished = ref<any[]>([]);
|
||||||
const componentPublished = ref<any[]>([]);
|
const componentPublished = ref<any[]>([]);
|
||||||
const step = ref<number>(0)
|
|
||||||
|
|
||||||
|
|
||||||
async function fetchPageByCode(slug: any) {
|
|
||||||
try {
|
|
||||||
const page = await $fetch(`/api/dynamic-page/get-by-code/${slug}`)
|
|
||||||
currentPage.value = {}
|
|
||||||
currentPage.value = page
|
|
||||||
|
|
||||||
setSectionPublished();
|
|
||||||
setComponentPublished();
|
|
||||||
} catch (error: any) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchPageById(id: string | number) {
|
|
||||||
try {
|
|
||||||
const { data } = await useFetch(`/api/dynamic-page/get-by-id/${id}`)
|
|
||||||
currentPage.value = {}
|
|
||||||
currentPage.value = data.value
|
|
||||||
} catch (error: any) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
const setSectionPublished = () => {
|
const setSectionPublished = () => {
|
||||||
const exsitsTemplate = ['None']
|
const exsitsTemplate = ['None']
|
||||||
@@ -64,13 +43,29 @@ export const useDynamicPageStore = defineStore("dynamicPageStore", () => {
|
|||||||
setComponentPublished();
|
setComponentPublished();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async function fetchPageByCode(slug: any) {
|
||||||
|
try {
|
||||||
|
const page = await $fetch(`/api/dynamic-page/get-by-code/${slug}`)
|
||||||
|
currentPage.value = {}
|
||||||
|
currentPage.value = page
|
||||||
|
|
||||||
|
setSectionPublished();
|
||||||
|
setComponentPublished();
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentPage,
|
||||||
|
sectionPublished,
|
||||||
|
componentPublished
|
||||||
|
}
|
||||||
|
} catch (error: any) {}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentPage,
|
currentPage,
|
||||||
sectionPublished,
|
sectionPublished,
|
||||||
componentPublished,
|
componentPublished,
|
||||||
|
|
||||||
fetchPageByCode,
|
fetchPageByCode,
|
||||||
fetchPageById,
|
|
||||||
setSectionPublished,
|
setSectionPublished,
|
||||||
setComponentPublished,
|
setComponentPublished,
|
||||||
setDataQuery,
|
setDataQuery,
|
||||||
|
|||||||
Reference in New Issue
Block a user