162162</template >
163163
164164<script setup>
165- import { onMounted , watch } from " vue" ;
165+ import { onMounted , watch , computed } from " vue" ;
166166import { useRoute , useRouter } from " vue-router" ;
167167import MainLayout from " @/layouts/FeedLayout.vue" ;
168+ import { useHead } from " @unhead/vue" ;
168169import { useDynamicPage } from " @/composables/useDynamicPage" ;
169170import {
170171 ExclamationTriangleIcon ,
@@ -186,6 +187,44 @@ const {
186187 formatDate ,
187188} = useDynamicPage ();
188189
190+ const pageDescription = computed (() => {
191+ if (pageData .value .meta_description ) {
192+ return pageData .value .meta_description ;
193+ }
194+
195+ if (! pageData .value .content ) {
196+ return ` Learn more about ${ pageTitle .value } on Loops` ;
197+ }
198+
199+ const tempDiv = document .createElement (" div" );
200+ tempDiv .innerHTML = pageData .value .content ;
201+
202+ const text = tempDiv .textContent || tempDiv .innerText || " " ;
203+
204+ const cleanText = text .replace (/ \s + / g , " " ).trim ();
205+ return cleanText .length > 160
206+ ? cleanText .substring (0 , 157 ) + " ..."
207+ : cleanText;
208+ });
209+
210+ const pageUrl = computed (() => {
211+ return window .location .origin + route .fullPath ;
212+ });
213+
214+ useHead ({
215+ title: computed (() => ` ${ pageTitle .value } | Loops` ),
216+ meta: computed (() => [
217+ { name: " description" , content: pageDescription .value },
218+ { property: " og:title" , content: pageTitle .value },
219+ { property: " og:description" , content: pageDescription .value },
220+ { property: " og:type" , content: " article" },
221+ { property: " og:url" , content: pageUrl .value },
222+ { name: " twitter:card" , content: " summary" },
223+ { name: " twitter:title" , content: pageTitle .value },
224+ { name: " twitter:description" , content: pageDescription .value },
225+ ]),
226+ });
227+
189228watch (
190229 () => currentSlug .value ,
191230 (newSlug , oldSlug ) => {
0 commit comments