Hosting Modes
PageGun offers three distinct hosting modes to fit different use cases and technical requirements. Choose the mode that best matches your project needs and technical constraints.
Overview Comparison
| Feature | Full Host | Rewrite | Data Mode |
|---|---|---|---|
| Hosting | Complete site on PageGun | Your existing domain | Your infrastructure |
| Domain | pagegun.dev or custom | Your domain | Your domain |
| Performance | Optimized CDN | Your server + PageGun API | Your infrastructure |
| Control | PageGun managed | Hybrid control | Full control |
| Complexity | Lowest | Medium | Highest |
| Use Case | New sites, landing pages | Existing sites + new pages | Headless CMS |
Full Host Mode
Complete website hosting on PageGun's infrastructure
Full Host is the simplest option where PageGun hosts your entire website. Perfect for new projects, landing pages, and sites that don't need complex backend integration.
How It Works
- Create pages in PageGun dashboard or via API
- Publish pages to make them live
- Access via
yourproject.pagegun.devor custom domain
Features
✅ CDN-optimized delivery - Global edge caching for fast loading
✅ SSL certificates - Automatic HTTPS for all domains
✅ Custom domains - Use your own domain with DNS pointing
✅ SEO optimization - Server-side rendering and meta tags
✅ Analytics integration - Built-in Google Analytics support
✅ Form handling - Contact forms work out of the box
Configuration
// API example - Create project in Full Host mode
const project = await fetch('https://api.pagegun.com/projects', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'My Website',
hosting_mode: 'full_host',
subdomain: 'mysite', // Creates mysite.pagegun.dev
custom_domain: 'mywebsite.com' // Optional
})
});DNS Setup (Custom Domain)
# A Record
mywebsite.com → 192.168.1.100 (PageGun IP)
# CNAME Record (alternative)
mywebsite.com → mysite.pagegun.devBest For
- New websites starting from scratch
- Landing pages for marketing campaigns
- Documentation sites that need to be fast and reliable
- Portfolio sites for individuals or agencies
- Marketing microsites for specific campaigns
Rewrite Mode
Integrate PageGun pages with your existing website
Rewrite mode lets you add PageGun-powered pages to your existing website without changing your hosting setup. Your server fetches and serves PageGun content seamlessly.
How It Works
- Create pages in PageGun (draft or published)
- Configure rewrite rules on your web server
- Server fetches content from PageGun API when requested
- Serve integrated content as if it's part of your site
Architecture Flow
User Request → Your Server → PageGun API → Rendered Page → User
↓ ↓ ↓ ↓
1. GET /blog 2. Check cache 3. Fetch data 4. Serve HTMLFeatures
✅ Seamless integration - Pages appear as part of your existing site
✅ Your existing domain - No DNS changes required
✅ Flexible routing - Control which URLs use PageGun
✅ Mixed content - Combine PageGun pages with existing pages
✅ Server-side rendering - SEO-friendly with your existing setup
✅ Custom headers - Add authentication, caching rules, etc.
Server Configuration Examples
Nginx
server {
listen 80;
server_name mywebsite.com;
# Existing site routes
location / {
proxy_pass http://your-app-server;
}
# PageGun rewrite routes
location ~ ^/(blog|landing|docs)/ {
proxy_pass https://api.pagegun.com/render$request_uri;
proxy_set_header Authorization "Bearer $pagegun_api_key";
proxy_set_header Host $host;
proxy_cache pagegun_cache;
proxy_cache_valid 200 5m;
}
}Apache
<VirtualHost *:80>
ServerName mywebsite.com
# Existing site
ProxyPass / http://your-app-server/
# PageGun routes
RewriteEngine On
RewriteRule ^/(blog|landing|docs)/(.*) https://api.pagegun.com/render/$1/$2 [P,L]
ProxyPassReverse /(blog|landing|docs)/ https://api.pagegun.com/render/
</VirtualHost>Node.js Express
const express = require('express');
const axios = require('axios');
const app = express();
// Existing routes
app.get('/', (req, res) => {
res.render('home');
});
// PageGun rewrite middleware
app.use(['/blog', '/landing', '/docs'], async (req, res) => {
try {
const response = await axios.get(`https://api.pagegun.com/render${req.path}`, {
headers: {
'Authorization': `Bearer ${process.env.PAGEGUN_API_KEY}`,
'Host': req.headers.host
}
});
res.set(response.headers);
res.send(response.data);
} catch (error) {
res.status(error.response?.status || 500).send('Page not found');
}
});Caching Strategy
// Implement smart caching
const cache = new Map();
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
app.use('/pagegun/*', async (req, res) => {
const cacheKey = req.path;
const cached = cache.get(cacheKey);
if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
return res.send(cached.content);
}
try {
const response = await fetchFromPageGun(req.path);
cache.set(cacheKey, {
content: response.data,
timestamp: Date.now()
});
res.send(response.data);
} catch (error) {
res.status(500).send('Error loading page');
}
});Best For
- Existing websites that want to add new page types
- Blogs on existing sites - Add a
/blogsection powered by PageGun - Landing page campaigns - Create
/campaign/xyzpages quickly - Documentation sections - Add
/docsto your product site - A/B testing - Test new page designs without affecting main site
Data Mode
Headless CMS approach - fetch data, render yourself
Data Mode treats PageGun as a headless CMS. You fetch structured data via API and render it in your own application with complete control over the presentation layer.
How It Works
- Create content in PageGun dashboard or API
- Fetch structured data via PageGun API
- Render in your app using your preferred framework
- Handle caching and optimization in your application
API Data Structure
// Fetch page data
const response = await fetch('https://api.pagegun.com/pages/page_123', {
headers: {
'Authorization': `Bearer ${API_KEY}`
}
});
const page = await response.json();
// Structured data example
{
"id": "page_123",
"page_name": "Product Landing",
"slug": "product",
"type": "page",
"config": {
"sections": [
{
"id": "hero-1",
"type": "hero",
"props": {
"headline": "Build Amazing Websites",
"subheadline": "Create without code",
"cta_text": "Get Started",
"cta_url": "/signup"
}
}
]
}
}Implementation Examples
React Implementation
import { useState, useEffect } from 'react';
import { HeroSection, FeaturesSection, CTASection } from './sections';
const PageGunPage = ({ pageId }) => {
const [pageData, setPageData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchPageData(pageId)
.then(data => {
setPageData(data);
setLoading(false);
})
.catch(console.error);
}, [pageId]);
if (loading) return <LoadingSpinner />;
if (!pageData) return <NotFound />;
return (
<div className="pagegun-page">
<SEOHead
title={pageData.meta.title}
description={pageData.meta.description}
image={pageData.og_image_url}
/>
{pageData.config.sections.map(section => (
<SectionRenderer
key={section.id}
type={section.type}
props={section.props}
/>
))}
</div>
);
};
const SectionRenderer = ({ type, props }) => {
const components = {
'hero': HeroSection,
'features': FeaturesSection,
'cta': CTASection
};
const Component = components[type];
return Component ? <Component {...props} /> : null;
};Next.js with SSG
// pages/[...slug].js
export async function getStaticProps({ params }) {
const slug = params.slug.join('/');
try {
const pageData = await fetchPageBySlug(slug);
return {
props: { pageData },
revalidate: 300 // Revalidate every 5 minutes
};
} catch (error) {
return { notFound: true };
}
}
export async function getStaticPaths() {
const pages = await fetchAllPages();
const paths = pages.map(page => ({
params: { slug: page.slug.split('/') }
}));
return {
paths,
fallback: 'blocking'
};
}
export default function DynamicPage({ pageData }) {
return <PageGunRenderer data={pageData} />;
}Vue.js Implementation
<template>
<div class="pagegun-page">
<component
v-for="section in pageData.config.sections"
:key="section.id"
:is="getSectionComponent(section.type)"
v-bind="section.props"
/>
</div>
</template>
<script>
import HeroSection from '@/components/sections/HeroSection.vue';
import FeaturesSection from '@/components/sections/FeaturesSection.vue';
export default {
components: {
HeroSection,
FeaturesSection
},
async asyncData({ params, $axios }) {
const pageData = await $axios.$get(`/api/pages/${params.id}`);
return { pageData };
},
methods: {
getSectionComponent(type) {
const mapping = {
'hero': 'HeroSection',
'features': 'FeaturesSection'
};
return mapping[type] || 'div';
}
}
};
</script>Advanced Patterns
Multi-language Support
const getLocalizedContent = async (pageId, locale = 'en') => {
const response = await fetch(`https://api.pagegun.com/pages/${pageId}?locale=${locale}`, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
return response.json();
};
// Use in components
const page = await getLocalizedContent('page_123', 'es');Content Personalization
const getPersonalizedContent = async (pageId, userId) => {
const baseContent = await fetchPageData(pageId);
const userSegment = await getUserSegment(userId);
// Modify content based on user segment
if (userSegment === 'enterprise') {
baseContent.config.sections[0].props.headline = 'Enterprise Solutions';
}
return baseContent;
};Performance Optimization
// Implement intelligent caching
const cache = new Map();
const CDN_CACHE_TTL = 3600; // 1 hour
app.get('/api/page/:id', async (req, res) => {
const cacheKey = `page:${req.params.id}`;
// Check memory cache first
if (cache.has(cacheKey)) {
return res.json(cache.get(cacheKey));
}
try {
const pageData = await fetchFromPageGun(req.params.id);
// Cache in memory and CDN
cache.set(cacheKey, pageData);
res.set('Cache-Control', `public, max-age=${CDN_CACHE_TTL}`);
res.json(pageData);
} catch (error) {
res.status(500).json({ error: 'Failed to load page' });
}
});Best For
- Custom applications that need specific design systems
- Multi-platform content - Web, mobile app, desktop
- Advanced integrations - E-commerce, user authentication, analytics
- Performance-critical sites - Custom optimization strategies
- Complex workflows - Content approval, scheduling, A/B testing
- Headless architecture - Microservices, API-first approach
Migration Guide
From Full Host to Rewrite
- Set up rewrite rules on your existing server
- Test page rendering in staging environment
- Update DNS gradually using CNAME records
- Monitor performance and adjust caching
From Rewrite to Data Mode
- Build rendering components for your application
- Implement API fetching with proper error handling
- Add caching strategy for performance
- Deploy and test thoroughly before switching
From Data Mode to Full Host
- Export content via API
- Create new Full Host project
- Import content and configure settings
- Update DNS to point to PageGun servers
Decision Framework
Choose Full Host if:
- ✅ Building a new website
- ✅ Want zero server maintenance
- ✅ Need fast global delivery
- ✅ Prefer simplicity over control
Choose Rewrite if:
- ✅ Have existing website/infrastructure
- ✅ Want to add specific page types (blog, landing pages)
- ✅ Need seamless integration with current site
- ✅ Want to test PageGun gradually
Choose Data Mode if:
- ✅ Need complete control over presentation
- ✅ Have complex technical requirements
- ✅ Building multi-platform applications
- ✅ Want to integrate deeply with existing systems
FAQ
Can I switch between hosting modes?
Yes, you can migrate between hosting modes. The process involves updating your project configuration and potentially changing your DNS setup. Content remains accessible via API in all modes.
Do all features work in every mode?
Most features work across all modes, but some are mode-specific:
- Form submissions: Available in Full Host and Rewrite, custom handling needed in Data Mode
- CDN optimization: Built-in for Full Host, manual setup for others
- SSL certificates: Automatic in Full Host, manual setup for others
What about SEO in different modes?
All modes support SEO, but implementation differs:
- Full Host: SEO handled automatically
- Rewrite: Your server handles SEO using PageGun data
- Data Mode: You implement SEO in your application
Can I use multiple modes in one project?
No, each project uses one hosting mode. However, you can create multiple projects with different modes and cross-link between them.
What are the performance implications?
- Full Host: Fastest, globally cached
- Rewrite: Depends on your server performance and caching
- Data Mode: Depends on your implementation and caching strategy