Server-Side Rendering
Implement SSR authentication with Nuvix for Next.js, SvelteKit, Nuxt, and other SSR frameworks.
Server-side rendering (SSR) is fully supported with Nuvix. Build authenticated applications with Next.js, SvelteKit, Nuxt, Astro, and any SSR framework.
SSR renders pages on the server and sends fully rendered HTML to the browser, improving performance and SEO compared to client-side rendering (CSR).
SSR authentication flow
In client-side apps, authentication happens directly in the browser. With SSR, your server handles authentication and manages sessions through secure cookies.
How it works
- User enters credentials in their browser
- Browser sends credentials to your server
- Server uses Nuvix SDK to authenticate the user
- Server creates a session cookie for the client
- Browser automatically includes the cookie with future requests
- Server uses the cookie to make authenticated requests to Nuvix
SSR requires server-side SDK usage. The server manages authentication state and passes it to the client through secure cookies.
Initialize clients
You'll need two Nuvix clients for SSR applications:
Admin client
Use the admin client for operations that bypass permissions or rate limits. Requires an API key with proper scopes.
import { Client } from '@nuvix/client';
const adminClient = new Client()
    .setEndpoint('https://api.nuvix.in/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<YOUR_API_KEY>'); // Server-side API keyAdmin clients bypass permissions and rate limits. Use them carefully and only for server-side operations.
Session client
Create a new session client for each request. Never share clients between requests.
import { Client } from '@nuvix/client';
function createSessionClient(req) {
    const sessionClient = new Client()
        .setEndpoint('https://api.nuvix.in/v1')
        .setProject('<PROJECT_ID>');
    
    // Get session from cookie
    const session = req.cookies['a_session_<PROJECT_ID>'];
    if (session) {
        sessionClient.setSession(session);
    }
    
    return sessionClient;
}Creating email/password sessions
Create a login endpoint that accepts credentials and returns a session cookie.
import express from 'express';
import { Client } from '@nuvix/client';
const app = express();
// Initialize admin client
const adminClient = new Client()
    .setEndpoint('https://api.nuvix.in/v1')
    .setProject('<PROJECT_ID>')
    .setKey('<YOUR_API_KEY>');
app.post('/login', async (req, res) => {
    const { email, password } = req.body;
    const account = new Account(adminClient);
    
    try {
        // Create session with Nuvix
        const session = await nx.account.createEmailPasswordSession(email, password);
        
        // Set secure session cookie
        res.cookie('a_session_<PROJECT_ID>', session.secret, {
            httpOnly: true,
            secure: true,
            sameSite: 'strict',
            expires: new Date(session.expire),
            path: '/'
        });
        
        res.json({ success: true });
    } catch (error) {
        res.status(401).json({ 
            success: false, 
            error: 'Invalid credentials' 
        });
    }
});Always use httpOnly, secure, and sameSite cookie options to prevent XSS attacks and ensure cookies are only sent over HTTPS.
Making authenticated requests
Use the session cookie to make authenticated requests on behalf of the user.
app.get('/user', async (req, res) => {
    // Get session from cookie
    const session = req.cookies['a_session_<PROJECT_ID>'];
    
    if (!session) {
        return res.status(401).json({ error: 'Unauthorized' });
    }
    
    // Create session client
    const sessionClient = new Client()
        .setEndpoint('https://api.nuvix.in/v1')
        .setProject('<PROJECT_ID>')
        .setSession(session);
    
    const account = new Account(sessionClient);
    
    try {
        const user = await nx.account.get();
        res.json({ success: true, user });
    } catch (error) {
        res.status(401).json({ error: 'Session invalid' });
    }
});Unauthenticated requests
Handle requests from users who aren't logged in using guest sessions or admin clients.
Guest sessions
Create anonymous sessions for users who haven't authenticated:
app.post('/guest-session', async (req, res) => {
    const account = new Account(adminClient);
    
    try {
        const session = await nx.account.createAnonymousSession();
        
        res.cookie('a_session_<PROJECT_ID>', session.secret, {
            httpOnly: true,
            secure: true,
            sameSite: 'strict',
            expires: new Date(session.expire),
            path: '/'
        });
        
        res.json({ success: true });
    } catch (error) {
        res.status(500).json({ error: 'Failed to create guest session' });
    }
});OAuth2 with SSR
Implement OAuth2 authentication with two server endpoints:
Redirect to OAuth provider
app.get('/oauth', async (req, res) => {
    const account = new Account(adminClient);
    
    const redirectUrl = await nx.account.createOAuth2Token({
        provider: 'github',
        success: 'https://yourapp.com/oauth/success',
        failure: 'https://yourapp.com/oauth/failure'
    });
    
    res.redirect(redirectUrl);
});Handle OAuth callback
app.get('/oauth/success', async (req, res) => {
    const { userId, secret } = req.query;
    const account = new Account(adminClient);
    
    try {
        const session = await nx.account.createSession(userId, secret);
        
        res.cookie('a_session_<PROJECT_ID>', session.secret, {
            httpOnly: true,
            secure: true,
            sameSite: 'strict',
            expires: new Date(session.expire),
            path: '/'
        });
        
        res.redirect('/dashboard');
    } catch (error) {
        res.redirect('/login?error=oauth_failed');
    }
});Rate limits and security
Handling rate limits
Unauthenticated requests from your server share the same rate limit. Use authenticated requests or admin clients to bypass limits:
// Rate limited - all server requests share the same limit
const publicData = await databases.listDocuments('public', 'posts');
// Bypasses rate limits - uses API key
const adminData = await adminDatabases.listDocuments('admin', 'users');Security headers
Set forwarded user agent for security tracking:
// Set the end user's user agent
sessionClient.setForwardedUserAgent(req.headers['user-agent']);Framework examples
How is this guide?
Last updated on