slogan3

Ontwikkel een Vue.js Component met Server-Side Rendering (SSR) Integratie

description

Met deze prompt kun je Vue.js componenten ontwikkelen die optimaal presteren in server-side rendering omgevingen, wat leidt tot snellere laadtijden en betere SEO. Het helpt je ook om de architectuur van je componenten aan te passen aan SSR-frameworks, wat uniek is ten opzichte van andere prompts die zich op client-side ontwikkeling richten.

prompt

Help me een Vue.js component te maken dat geoptimaliseerd is voor server-side rendering (SSR). Beschrijf hoe ik de code moet structureren zodat deze goed samenwerkt met een SSR-framework zoals N ...

try_prompt

generate_helper
disclaimerOnPageApi

ai_answers

provider: openai
model: gpt-4.1-nano
Hier is een overzicht van hoe je een Vue.js component kunt structureren voor SSR, bijvoorbeeld in Nuxt.js of Vue 3 SSR, inclusief de nodige optimalisaties: 1. **Component Structuur en Opzet** Gebruik een standaard Vue 3 Single File Component (SFC) structuur, met gescheiden `<template>`, `<script>`, en `<style>` secties. 2. **Gebruik van `<script setup>`** Voor Vue 3, is het aanbevolen om `<script setup>` te gebruiken voor eenvoud en betere SSR-ondersteuning. 3. **Data en State Management** Gebruik `asyncData()` of `fetch()` methoden (bijvoorbeeld in Nuxt) om data server-side op te halen. In Vue 3 SSR zonder Nuxt kun je data in `setup()` laden en zorgen dat deze niet client-only is. 4. **Meta tags en structured data** Voor SSR moeten meta tags en structured data (zoals JSON-LD) op de server gerenderd worden. In Nuxt.js doe je dit via de `<head>` property of `useHead()` uit `@vueuse/head`. 5. **Specifieke SSR-optimalisaties** - Gebruik geen client-only code in de `<script setup>` die niet op de server kan draaien. - Laad data in lifecycle hooks die SSR ondersteunen (`asyncData()`, `fetch()`, of setup). - Zet meta tags en structured data in de `head()` functie of `useHead()` zodat ze server-side gerenderd worden. --- ### Voorbeeldstructuur (met Nuxt 3 en `<script setup>`) ```vue <template> <div> <h1>Productoverzicht</h1> <!-- Filters en sorteeropties --> <div> <label> Sorteren op: <select v-model="sortOption" @change="sortProducts"> <option value="name">Naam</option> <option value="price">Prijs</option> </select> </label> <!-- Filters --> <input v-model="filterText" placeholder="Zoek producten" /> </div> <!-- Productenlijst --> <ul> <li v-for="product in filteredProducts" :key="product.id"> {{ product.name }} - €{{ product.price }} </li> </ul> </div> </template> <script setup> import { ref, computed } from 'vue' import { useHead } from '@vueuse/head' // Data ophalen const products = ref([]) // Simuleer data ophalen, bij SSR gebeurt dit server-side // In Nuxt 3 kan je ook `useAsyncData()` gebruiken async function fetchProducts() { // Bijvoorbeeld via API const response = await fetch('/api/products') products.value = await response.json() } // Roep fetch bij component initialisatie fetchProducts() // Filteren en sorteren const filterText = ref('') const sortOption = ref('name') const filteredProducts = computed(() => { return products.value .filter(p => p.name.toLowerCase().includes(filterText.value.toLowerCase())) .sort((a, b) => { if (sortOption.value === 'name') { return a.name.localeCompare(b.name) } else if (sortOption.value === 'price') { return a.price - b.price } }) }) function sortProducts() { // optioneel: extra logica } // Meta tags en structured data server-side renderen useHead({ title: 'Productoverzicht', meta: [ { name: 'description', content: 'Bekijk ons assortiment producten' } ], script: [ { type: 'application/ld+json', children: JSON.stringify({ "@context": "https://schema.org", "@type": "ItemList", "itemListElement": products.value.map((product, index) => ({ "@type": "Product", "name": product.name, "offers": { "@type": "Offer", "price": product.price } })) }) } ] }) </script> <style scoped> /* Styling voor overzicht, filters, etc. */ </style> ``` --- ### Samenvatting - **Data ophalen**: doe dat via SSR-vriendelijke methoden (`useAsyncData()` in Nuxt, `fetch()` in Vue 3 SSR). - **Meta en structured data**: zet ze in `useHead()` zodat ze server-side gerenderd worden. - **Component structuur**: gebruik `<script setup>`, en vermijd client-only code tenzij geconditioneerd. - **Performance**: minimaliseer client-side hydration door data en meta-data server-side te renderen. Wil je een voorbeeld voor een specifiek SSR-framework of meer details?
provider: deepseek
model: deepseek-chat
Zeker! Hier is een voorbeeld van een SSR-geoptimaliseerd Vue.js component voor een productoverzicht, inclusief SSR-specifieke optimalisaties: ```vue <template> <div class="product-overview"> <!-- Meta tags worden via SSR ingevoegd --> <Head> <title>{{ pageTitle }}</title> <meta name="description" :content="metaDescription" /> <script type="application/ld+json" v-html="structuredData" /> </Head> <!-- Filter en sorteer opties --> <div class="filters"> <select v-model="selectedCategory" @change="updateFilters"> <option value="">Alle categorieën</option> <option v-for="category in categories" :key="category" :value="category"> {{ category }} </option> </select> <select v-model="sortBy" @change="updateSorting"> <option value="name">Naam A-Z</option> <option value="price-asc">Prijs Laag-Hoog</option> <option value="price-desc">Prijs Hoog-Laag</option> </select> </div> <!-- Productlijst --> <div class="product-list"> <div v-for="product in filteredProducts" :key="product.id" class="product-item"> <h3>{{ product.name }}</h3> <p>€{{ product.price }}</p> </div> </div> </div> </template> <script> import { defineComponent, computed, ref } from 'vue' import { useHead } from '@unhead/vue' // Voor Vue 3 met Nuxt 3 export default defineComponent({ name: 'ProductOverview', async setup(props, { attrs }) { // Data ophalen - SSR compatible const { data: products } = await useAsyncData( 'products', () => $fetch('/api/products') ) const selectedCategory = ref('') const sortBy = ref('name') // Categorieën uit products halen const categories = computed(() => { return [...new Set(products.value.map(p => p.category))] }) // Gefilterde en gesorteerde producten const filteredProducts = computed(() => { let filtered = products.value if (selectedCategory.value) { filtered = filtered.filter(p => p.category === selectedCategory.value) } // Sorteren switch(sortBy.value) { case 'price-asc': return filtered.sort((a, b) => a.price - b.price) case 'price-desc': return filtered.sort((a, b) => b.price - a.price) default: return filtered.sort((a, b) => a.name.localeCompare(b.name)) } }) // SEO metadata const pageTitle = computed(() => selectedCategory.value ? `Producten - ${selectedCategory.value}` : 'Onze producten' ) const metaDescription = computed(() => `Bekijk onze ${filteredProducts.value.length} producten${selectedCategory.value ? ` in categorie ${selectedCategory.value}` : ''}` ) // Structured data voor SEO const structuredData = computed(() => { return JSON.stringify({ '@context': 'https://schema.org', '@type': 'ItemList', 'numberOfItems': filteredProducts.value.length, 'itemListElement': filteredProducts.value.slice(0, 10).map((product, index) => ({ '@type': 'ListItem', 'position': index + 1, 'item': { '@type': 'Product', 'name': product.name, 'price': product.price, 'category': product.category } })) }) }) // SSR Meta tags instellen useHead({ title: pageTitle, meta: [ { name: 'description', content: metaDescription } ], script: [ { type: 'application/ld+json', innerHTML: structuredData } ] }) return { products, selectedCategory, sortBy, categories, filteredProducts, pageTitle, metaDescription, structuredData } }, // Voor Nuxt 2 of Vue 2 SSR: async asyncData({ $axios }) { const products = await $axios.$get('/api/products') return { products } }, head() { return { title: this.pageTitle, meta: [ { hid: 'description', name: 'description', content: this.metaDescription } ], script: [ { type: 'application/ld+json', json: this.structuredData } ] } } }) </script> <style scoped> .product-overview { max-width: 1200px; margin: 0 auto; padding: 20px; } .filters { margin-bottom: 20px; display: flex; gap: 15px; } .product-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; } .product-item { border: 1px solid #ddd; padding: 15px; border-radius: 8px; } </style> ``` ## Belangrijke SSR-optimalisaties: ### 1. **Data Fetching** ```javascript // Gebruik SSR-compatible data fetching const { data: products } = await useAsyncData( 'products', () => $fetch('/api/products') ) ``` ### 2. **Meta Tags SSR** ```javascript // Vue 3 met Nuxt 3 useHead({ title: pageTitle, meta: [{ name: 'description', content: metaDescription }] }) // Voor Nuxt 2 head() { return { title: this.pageTitle, meta: [{ hid: 'description', name: 'description', content: this.metaDescription }] } } ``` ### 3. **Structured Data SSR** ```javascript const structuredData = computed(() => { return JSON.stringify({ '@context': 'https://schema.org', '@type': 'ItemList', // ... structured data }) }) ``` ### 4. **Projectstructuur voor SSR:** ``` src/ ├── components/ │ └── ProductOverview.vue ├── composables/ │ └── useProducts.js ├── pages/ │ └── products.vue └── nuxt.config.ts ``` ### 5. **Nuxt Config (nuxt.config.ts):** ```typescript export default defineNuxtConfig({ ssr: true, app: { head: { meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' } ] } } }) ``` ### 6. **SSR-specifieke overwegingen:** - Gebruik `useAsyncData` voor server-side data fetching - Vermijd browser-specifieke APIs in setup() - Gebruik `process.client` checks voor client-only code - Test altijd zowel server-side als client-side rendering Deze structuur zorgt voor optimale SEO, snelle initial load en correcte weergave van meta tags en structured data tijdens server-side rendering.