Server-Side Rendering (SSR)
Basic SSR Implementation
Integration with winter.serve and Template Engine
// src/entry-server.js
import { createSSRApp } from 'vue'; // Example framework-agnostic
import App from './App.vue';
import { renderToString } from 'winter-ssr'; // Assumed SSR renderer
import templateEngine from './template-engine';
export async function render(url) {
const app = createSSRApp(App, { url });
const html = await renderToString(app);
// Inject dynamic content using template engine
return templateEngine.render('layout', {
body: html,
title: 'WinterJS SSR Demo'
});
}
// src/template-engine.js
export default {
render(templateName, data) {
const templates = {
layout: (data) => `
<!DOCTYPE html>
<html>
<head>
<title>${data.title}</title>
</head>
<body>
${data.body}
</body>
</html>
`
};
return templates[templateName](data);
}
};
Server-Side Route Handling
// server.js
import http from 'http';
import { parse } from 'url';
import { render } from './src/entry-server';
const server = http.createServer(async (req, res) => {
const { pathname } = parse(req.url);
try {
const html = await render(pathname);
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(html);
} catch (err) {
res.writeHead(500);
res.end('Server Error');
console.error(err);
}
});
server.listen(3000, () => {
console.log('SSR Server running on http://localhost:3000');
});
Data Prefetching and State Synchronization
Server-Side Data Prefetching
// src/entry-server.js
export async function render(url) {
const app = createSSRApp(App, { url });
// Execute route-level data prefetching
const matchedComponents = getMatchedComponents(url);
await Promise.all(
matchedComponents.map(Component => {
if (Component.asyncData) {
return Component.asyncData({ store, route: url });
}
})
);
// Get prefetched state
const initialState = store.getState();
// Render application
const html = await renderToString(app);
return {
html,
initialState // Inject into client
};
}
Client-Side State Synchronization
// src/entry-client.js
import { createApp } from 'vue';
import App from './App.vue';
import { hydrate } from 'winter-ssr';
import { createStore } from './store';
const store = createStore();
const app = createApp(App);
// Initialize client store with server-injected state
if (window.__INITIAL_STATE__) {
store.replaceState(window.__INITIAL_STATE__);
}
hydrate(app, document.getElementById('app'), () => {
// Client activation complete
app.mount('#app');
});
Component-Level Caching Strategy
// src/cache-strategy.js
export const componentCache = new Map();
export function getCacheKey(component, props) {
return `${component.name}-${JSON.stringify(props)}`;
}
export async function renderWithCache(component, props) {
const key = getCacheKey(component, props);
if (componentCache.has(key)) {
return componentCache.get(key);
}
const html = await renderComponent(component, props);
componentCache.set(key, html);
// Set cache expiration
if (componentCache.size > 1000) {
componentCache.delete(componentCache.keys().next().value);
}
return html;
}
Streaming SSR Implementation
// src/stream-renderer.js
export async function streamRender(app) {
const stream = new ReadableStream({
start(controller) {
const context = { write: controller.enqueue.bind(controller) };
// Chunked rendering
renderApp(app, context, (chunk) => {
controller.enqueue(new TextEncoder().encode(chunk));
}).then(() => {
controller.close();
}).catch(err => {
controller.error(err);
});
}
});
return stream;
}
SSR Security and Error Handling
Security Measures
// src/security-middleware.js
export function sanitizeInput(input) {
return input.replace(/[<>]/g, '');
}
export function helmetMiddleware(req, res, next) {
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('Content-Security-Policy', "default-src 'self'");
next();
}
// Use in rendering flow
export async function safeRender(url) {
try {
const sanitizedUrl = sanitizeInput(url);
return await render(sanitizedUrl);
} catch (err) {
console.error('SSR Error:', err);
return {
html: '<h1>500 Internal Server Error</h1>',
statusCode: 500
};
}
}
SSR Use Cases
SEO Optimization Implementation
// src/seo-meta.js
export function generateMetaTags(page) {
const meta = {
title: page.title,
description: page.description,
keywords: page.keywords,
og: {
title: page.ogTitle || page.title,
description: page.ogDescription || page.description,
image: page.ogImage || '/default-og.png'
}
};
return `
<title>${meta.title}</title>
<meta name="description" content="${meta.description}">
<meta name="keywords" content="${meta.keywords}">
<meta property="og:title" content="${meta.og.title}">
<meta property="og:description" content="${meta.og.description}">
<meta property="og:image" content="${meta.og.image}">
`;
}
Static Site Generation (SSG)
Basic SSG Implementation
winter.build Configuration
// winter.config.js
export default {
ssg: {
entry: 'src/entry-static.js',
output: {
path: 'dist',
clean: true
},
routes: async () => {
const { getStaticPaths } = await import('./src/routes');
return getStaticPaths();
}
}
};
// src/entry-static.js
import { createStaticApp } from 'winter-static'; // Assumed static site generator
import App from './App.vue';
export async function generateStaticSite() {
const app = createStaticApp(App);
const paths = await getStaticPaths();
for (const path of paths) {
const html = await app.render(path);
writeFileSync(`dist${path}.html`, html);
}
}
Content Management and Dynamic Routing
Dynamic Route Generation
// src/routes.js
export async function getStaticPaths() {
const posts = await fetch('https://api.winterjs.com/posts')
.then(res => res.json());
return {
paths: posts.map(post => ({
params: { slug: post.slug }
})),
fallback: 'blocking' // 404 handling strategy
};
}
export async function getStaticProps({ params }) {
const post = await fetch(`https://api.winterjs.com/posts/${params.slug}`)
.then(res => res.json());
return {
props: { post },
revalidate: 60 // ISR: Incremental Static Regeneration
};
}
Incremental Static Regeneration (ISR)
// winter.config.js
export default {
ssg: {
revalidate: {
default: 60, // Default 60 seconds revalidation
paths: {
'/blog/*': 300, // Blog posts revalidate every 5 minutes
'/products/*': 3600 // Product pages revalidate every 1 hour
}
}
}
};
Static Asset Optimization
// winter.config.js
export default {
ssg: {
assets: {
compress: {
js: true,
css: true,
images: {
webp: true,
avif: true
}
},
preload: ['critical.css', 'main.js']
}
}
};
SSG and CMS Integration
Headless CMS Connection
// src/cms-integration.js
export async function fetchCMSContent() {
const token = process.env.CMS_TOKEN;
const response = await fetch('https://cms.winterjs.com/api/content', {
headers: {
'Authorization': `Bearer ${token}`
}
});
if (!response.ok) {
throw new Error('Failed to fetch CMS content');
}
return response.json();
}
// Use in static generation
export async function getStaticProps() {
const content = await fetchCMSContent();
return {
props: { content },
revalidate: 3600
};
}
SSG Use Cases
Documentation Site Generation
// src/docs-generator.js
export async function generateDocs() {
const files = await glob('docs/**/*.md');
const docsRoutes = files.map(file => ({
params: {
slug: file.replace('docs/', '').replace('.md', '')
}
}));
return {
paths: docsRoutes,
fallback: false
};
}
export async function getStaticProps({ params }) {
const content = await markdownToHtml(`docs/${params.slug}.md`);
return {
props: { content }
};
}
Real-Time Application Development
WebSocket Real-Time Communication
Basic WebSocket Implementation
// server.js
import { WebSocketServer } from 'ws';
const wss = new WebSocketServer({ port: 8080 });
const clients = new Set();
wss.on('connection', (ws) => {
clients.add(ws);
ws.on('message', (message) => {
// Broadcast message to all clients
for (const client of clients) {
if (client.readyState === WebSocket.OPEN) {
client.send(message);
}
}
});
ws.on('close', () => {
clients.delete(ws);
});
});
// Client implementation
const ws = new WebSocket('ws://localhost:8080');
ws.onmessage = (event) => {
console.log('Received:', event.data);
};
function sendMessage(message) {
ws.send(JSON.stringify(message));
}
GraphQL and WinterJS Integration
Apollo Client Configuration
// src/apollo-client.js
import { ApolloClient, InMemoryCache, HttpLink } from '@apollo/client/core';
export const apolloClient = new ApolloClient({
link: new HttpLink({
uri: 'https://api.winterjs.com/graphql',
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`
}
}),
cache: new InMemoryCache()
});
// Usage in component
import { useQuery } from '@vue/apollo-composable'; // Example framework-agnostic
import { gql } from '@apollo/client/core';
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
}
}
`;
export default {
setup() {
const { result, loading, error } = useQuery(GET_USER, {
id: '123'
});
return { user: result, loading, error };
}
};
Real-Time Collaborative Editing
CRDT Algorithm Implementation
// src/crdt.js
export class CRDTDocument {
constructor() {
this.siteId = Math.random().toString(36).substr(2, 9);
this.clock = 0;
this.chars = new Map(); // Character position mapping
}
insert(position, char) {
this.clock++;
const id = { siteId: this.siteId, clock: this.clock };
this.chars.set(position, { id, char });
this.sortChars();
}
delete(position) {
this.clock++;
const id = { siteId: this.siteId, clock: this.clock };
this.chars.set(position, { id, deleted: true });
this.sortChars();
}
sortChars() {
this.chars = new Map([...this.chars.entries()].sort((a, b) => a[0] - b[0]));
}
getText() {
return [...this.chars.values()]
.filter(char => !char.deleted)
.map(char => char.char)
.join('');
}
}
Message Compression and Batching
// server.js
import zlib from 'zlib';
wss.on('connection', (ws) => {
let messageBuffer = [];
let batchTimer;
ws.on('message', (message) => {
messageBuffer.push(message);
// Batch processing timer
if (!batchTimer) {
batchTimer = setTimeout(() => {
const batch = messageBuffer.join('\n');
zlib.deflate(batch, (err, compressed) => {
if (!err) {
ws.send(compressed);
}
});
messageBuffer = [];
batchTimer = null;
}, 50); // 50ms batch processing window
}
});
});
Real-Time Application Security Controls
Authentication and Authorization
// server.js
import jwt from 'jsonwebtoken';
wss.on('connection', (ws, req) => {
const token = req.url.split('token=')[1];
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET);
ws.user = decoded;
ws.on('message', (message) => {
if (!hasPermission(ws.user, message)) {
ws.send(JSON.stringify({ error: 'Unauthorized' }));
return;
}
// Process message...
});
} catch (err) {
ws.close(1008, 'Invalid token');
}
});
function hasPermission(user, message) {
// Permission check logic
return user.roles.includes('admin') ||
message.type !== 'delete';
}