@sututu/vue
v0.1.0
Published
Vue.js SSR/CSR plugin for Sututu framework
Readme
@sututu/vue
Vue 3 SSR/CSR Fastify plugin for the Sututu framework. Provides hybrid server-side and client-side rendering with minimal configuration.
Features
- Hybrid SSR/CSR - Server-side rendering with client-side hydration
- Zero boilerplate - Virtual entry files generated automatically
- Hot Module Replacement - Full HMR support in development
- i18n ready - Built-in internationalization with pluralization
- Error handling - Automatic error boundaries and pages
- Universal fetch -
useFetchworks on server and client - Head management -
useHeadfor meta tags and SEO
Installation
npm install @sututu/vueQuick Start
Create three files in your src/client directory:
src/client/
├── App.vue
├── routes.js
└── index.htmlApp.vue
<template>
<SututuOutlet />
</template>routes.js
export default [
{
path: '/',
name: 'home',
component: () => import('./views/Home.vue')
}
]index.html
<!DOCTYPE html>
<html lang="{{lang}}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
{{meta}}
{{link}}
</head>
<body>
<div id="app">{{app}}</div>
{{state}}
<script type="module" src="/entry-client.js"></script>
</body>
</html>Composables
useFetch
Universal data fetching that works on server and client.
import { useFetch } from '@sututu/vue/composables'
const { data, error, pending, refresh } = useFetch('/api/users')Options:
timeout- Request timeout (default: 10s SSR, 30s CSR)lazy- Don't block SSR rendering
// Lazy fetch - loads on client after hydration
const { data } = useFetch('/api/recommendations', { lazy: true })
// Or use the shorthand
import { useLazyFetch } from '@sututu/vue/composables'
const { data } = useLazyFetch('/api/recommendations')useHead
Manage document head for SEO.
import { useHead } from '@sututu/vue/composables'
useHead({
title: 'My Page',
meta: [
{ name: 'description', content: 'Page description' },
{ property: 'og:title', content: 'Open Graph Title' }
],
link: [
{ rel: 'canonical', href: 'https://example.com/page' }
],
htmlAttrs: { lang: 'en' }
})useI18n
Internationalization with pluralization support.
import { useI18n } from '@sututu/vue/composables'
const { t, locale, formatDate, loadLocale } = useI18n()
// Simple translation
t('greeting') // "Hello"
// With interpolation
t('welcome', { name: 'John' }) // "Welcome, John!"
// Pluralization
t('items', { count: 1 }) // "1 item"
t('items', { count: 5 }) // "5 items"
// Date formatting
formatDate('2025-12-04T10:30:00Z') // "Dec 4, 2025, 10:30 AM"useError
Error handling utilities.
import { useError, createError } from '@sututu/vue/composables'
const { error, clearError } = useError()
// Throw a fatal error (will show error page)
throw createError({ statusCode: 404, message: 'Not found' })Components
SututuError
Built-in error page component.
<template>
<SututuError />
</template>
<script setup>
import { SututuError } from '@sututu/vue/components'
</script>SututuOutlet
Outlet component that shows content or error page. Internally renders <router-view /> and handles error display.
<template>
<SututuOutlet />
</template>Configuration
In your sututu.config.js:
export default {
vue: {
clientDir: 'src/client',
publicPath: 'dist/client'
},
locale: {
defaultLocale: 'en',
availableLocales: ['en', 'es', 'fr']
}
}Testing
# Run tests
npm test
# Run tests with coverage
npm run test:coverageTest coverage thresholds:
- Composables: 90% statements/lines
- Components: 80% statements/lines
- Global: 55% statements/lines
