Knowledge > Products > Pro Website > Sections
Pro Website Template Sections
Section Rendering Philosophy
Every section in UnifiedTemplate is conditional on data availability. If a church has not populated staff, the Staff section does not render -- there is no empty placeholder or "Coming Soon" stub. This means a brand-new Pro Website with no admin edits still looks complete: it shows the hero video, service times (from the church's PewSearch directory listing), map/contact, and footer. As the church adds content via the admin dashboard, sections progressively appear.
The template renders sections in a fixed order (listed below). There is no drag-and-drop section reordering. The order was designed based on visitor psychology: what matters most (who is this church, when do they meet) comes first; secondary content (events, sermons, giving) comes later.
Section Reference
Section 1: StickyNav
What it does: Renders a fixed-position navigation bar at the top of the page with anchor links to visible sections and the church logo.
Data source: Computed from which sections are visible (each section registers an anchor ID). Logo from premium_churches.logo_url.
Rendering logic:
IF logo_url exists:
Show logo image (max-height 48px, auto-width)
ELSE:
Show church name as text
Navigation links = array of {label, anchorId} for each visible section
Links use denomination-specific labels (e.g., "Mass Times" vs "Service Times")
Scroll behavior: smooth scroll to anchor on click
Sticky: position fixed at top, z-index above content, semi-transparent background
Mobile: collapses to hamburger menu
When it renders: Always. Every Pro Website page has navigation.
Visual adaptation: Background color and link hover color match the denomination family. Logo is rendered as-uploaded (no color transformation).
Section 2: Demo Badge
What it does: Shows a small "DEMO" indicator badge overlaying the page for test/demo churches.
Data source: Church UUID from premium_churches.church_id.
Rendering logic:
IF church_id starts with '00000000-0000-4000-a000-':
Show floating badge: "DEMO" in red/white
Position: top-right corner, below nav
ELSE:
Do not render
When it renders: Only for demo church UUIDs (those starting with the reserved demo prefix). This ensures demo pages are clearly distinguishable from real church pages during testing and sales demos.
Section 3: VideoHero
What it does: Full-width video background with church name overlay, tagline, and denomination-styled call-to-action.
Data source:
- Video:
premium_churches.hero_video_key(single) orpremium_churches.hero_slideshow_keys(array) - Church name:
churches.name - Tagline:
churches.description(first sentence or custom tagline if set)
Rendering logic:
IF hero_slideshow_keys is non-empty array:
Render slideshow: cycle through videos with crossfade
Each video: <video autoplay muted loop playsinline>
Poster image shown on mobile / while loading
ELSE:
video_key = hero_video_key OR 'church-entrance' (default)
Lookup video entry from video-library.ts
Render single <video autoplay muted loop playsinline>
Overlay:
Semi-transparent gradient (family-specific color)
Church name: large heading (family heading font)
Tagline: subtitle text below name
CTA button: "Plan Your Visit" or family-specific label, scrolls to What to Expect or Service Times
When it renders: Always. The hero section is the visual anchor of every Pro Website page. Even without a custom video selected, the default church-entrance video provides a professional first impression.
Visual adaptation:
- Liturgical: dark overlay with gold accent border, Playfair Display heading
- Protestant: blue gradient overlay, clean sans-serif heading
- Community: warm gradient overlay, modern rounded heading
Section 4: About
What it does: Displays the church's description/about text with denomination-appropriate styling.
Data source: churches.description (from the PewSearch directory listing, editable by church admin).
Rendering logic:
IF description exists and is non-empty:
Render description text in a styled card/section
Apply family-specific background and text styling
Max-width container for readability
ELSE:
Do not render
When it renders: When the church has a description. Most claimed churches have one from their directory listing.
Section 5: Beliefs & Values
What it does: Renders belief statement cards in a grid layout.
Data source: premium_churches.beliefs (JSONB array).
Rendering logic:
IF beliefs array exists and has items:
FOR each belief in beliefs:
Render card with:
- belief.title (bold heading)
- belief.description (body text)
Layout: responsive grid (2 columns desktop, 1 column mobile)
Family-specific card styling (border color, background)
ELSE:
Do not render
When it renders: Only when the church has added beliefs via the admin Content tab. This is opt-in content -- many churches may choose not to display belief statements on their website.
Section 6: VideoTransition (First)
What it does: A decorative video break between the upper content sections and the middle sections. Creates visual breathing room.
Data source: premium_churches.transition_video_key (default: transition-1).
Rendering logic:
video_key = transition_video_key OR 'transition-1'
Lookup video entry from video-library.ts
Render: <video autoplay muted loop playsinline>
Height: constrained (approximately 200-300px)
Width: full-width
No overlay text
When it renders: Always (when at least one section exists above and below it). Provides visual rhythm to the page.
Section 7: Service Times
What it does: Displays the church's service/meeting times in a structured, day-ordered grid.
Data source: premium_churches.custom_hours (JSONB, structured by day) OR fallback to churches.service_times from the directory listing.
Rendering logic:
IF custom_hours exists (Pro Website admin-edited):
Use custom_hours data
ELSE IF churches.service_times exists (directory fallback):
Use directory service times
ELSE:
Do not render
Day ordering: Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday
For each day with entries:
Show day name
For each service on that day:
Show label (e.g., "Morning Worship", "Evening Service", "Mass")
Show time (formatted)
Section heading uses family label:
liturgical/catholic: "Mass & Confession Times"
liturgical/orthodox: "Divine Liturgy Times"
protestant: "Service Times"
community: "Gathering Times"
When it renders: When any hours data exists. Most churches have service times from their directory listing, so this section renders for nearly all Pro Website pages.
Section 8: What to Expect
What it does: A first-visit information guide with 10 structured fields, designed to reduce visitor anxiety about attending a new church.
Data source: premium_churches.what_to_expect (JSONB object with 10 fields).
Fields:
| Field | Purpose | Example Content |
|---|---|---|
dress_code | What to wear | "Come as you are! Most people wear casual or business casual." |
parking | Where to park | "Free parking in our main lot off Oak Street. Greeters will direct you." |
children | Kids programs | "We have nursery (0-2), preschool (3-5), and elementary (K-5) programs during all services." |
first_visit | What happens | "Arrive 10 minutes early. A greeter will meet you at the door and help you find a seat." |
music_style | Worship style | "Contemporary worship with a full band, plus one traditional hymn each Sunday." |
service_length | How long | "Services typically last about 75 minutes." |
accessibility | Accessibility info | "Wheelchair accessible. Hearing assistance devices available at the welcome desk." |
communion | Communion practice | "We celebrate communion on the first Sunday of each month. All believers are welcome." |
coffee | Coffee/refreshments | "Free coffee and donuts in the lobby before and after every service!" |
guest_checkin | Guest registration | "Fill out a connection card in your seat or check in at the welcome desk." |
Rendering logic:
IF what_to_expect exists and has at least one non-empty field:
Render section with heading (family label: "What to Expect" / "Visiting Our Parish" / "Your First Visit")
FOR each field in what_to_expect:
IF field value is non-empty:
Render card with icon + field label + field value
Layout: responsive grid (2 columns desktop, 1 column mobile)
Each card has a contextual icon (parking icon for parking, kids icon for children, etc.)
ELSE:
Do not render
When it renders: Only when the church has populated at least one What to Expect field via the admin.
Section 9: Staff
What it does: Displays a staff directory with photos, names, titles, and bios in a responsive grid.
Data source: premium_churches.custom_staff (JSONB array).
Staff entry structure:
{
"name": "Pastor John Smith",
"title": "Senior Pastor",
"bio": "Pastor John has served our church for 15 years...",
"photo_url": "https://supabase.co/storage/v1/.../photo.jpg",
"order": 1
}
Rendering logic:
IF custom_staff exists and has items:
Sort by order field (ascending)
Render section heading (family label: "Staff" / "Parish Staff" / "Clergy & Staff" / "Our Team")
FOR each staff member:
Render card with:
- Photo (if photo_url exists, else default avatar placeholder)
- Name (bold)
- Title (subtitle)
- Bio (body text, truncated with expand on click if long)
Layout: 2x4 responsive grid (up to 4 columns on wide screens, 2 on tablet, 1 on mobile)
ELSE:
Do not render
When it renders: Only when the church has added staff via the admin. Staff photos are uploaded via POST /api/upload/staff-photo and stored in Supabase Storage.
Section 10: VideoTransition (Second)
What it does: Second decorative video break, identical in behavior to Section 6.
Data source: Same transition_video_key as Section 6.
When it renders: When sections exist above and below it that benefit from visual separation. Uses the same transition video as Section 6.
Section 11: Ministries
What it does: Displays ministry/program cards with names and descriptions.
Data source: premium_churches.custom_ministries (JSONB array).
Ministry entry structure:
{
"name": "Youth Group",
"description": "For students in grades 6-12. Meets Wednesday evenings at 6:30 PM.",
"order": 1
}
Rendering logic:
IF custom_ministries exists and has items:
Sort by order field (ascending)
Render section heading (family label: "Ministries" / "Parish Ministries" / "Get Involved")
FOR each ministry:
Render card with:
- Ministry name (heading)
- Description (body text)
Layout: responsive grid (3 columns desktop, 2 tablet, 1 mobile)
Card styling: family-specific border and accent colors
ELSE:
Do not render
When it renders: Only when the church has added ministries via the admin.
Section 12: Featured Sermon
What it does: Embeds a YouTube or Vimeo video player for the church's featured sermon, plus a grid of additional sermons if available.
Data source:
- Primary:
premium_churches.featured_video_urlOR first entry inpremium_churches.sermonsarray - Additional: remaining entries in
premium_churches.sermons
Rendering logic:
primary_video = featured_video_url OR sermons[0].video_url
IF primary_video exists:
Render section heading (family label: "Sermons" / "Homilies" / "Messages")
Render embedded video player (responsive iframe):
- YouTube: extract video ID, render youtube-nocookie embed
- Vimeo: extract video ID, render Vimeo player embed
IF sermons array has more than 1 entry:
Render grid of additional sermon cards:
- Sermon title
- Speaker name
- Date
- Thumbnail (auto-generated from video URL)
- Click to play (replaces primary player or opens in new tab)
ELSE:
Do not render
When it renders: When the church has set a featured_video_url or has at least one sermon in the sermons array.
Section 13: Events
What it does: Displays a list of upcoming events with date, time, and description.
Data source: premium_churches.events (JSONB array).
Event entry structure:
{
"title": "Easter Sunday Service",
"date": "2026-04-05",
"time": "9:00 AM",
"description": "Join us for a special Easter celebration with worship, message, and egg hunt for kids.",
"location": "Main Sanctuary"
}
Rendering logic:
IF events array exists and has items:
Filter to future events (date >= today)
Sort by date ascending (soonest first)
Render section heading (family label: "Upcoming Events" / "Parish Events" / "What's Happening")
FOR each event:
Render event card with:
- Date (formatted: "April 5, 2026")
- Time
- Title (heading)
- Description
- Location (if provided)
Layout: vertical list or 2-column grid depending on count
ELSE:
Do not render
When it renders: Only when the church has added events and at least one is in the future.
Known gap: No recurring event support. Each occurrence must be entered individually. This is a known admin UX limitation for future improvement.
Section 14: Giving
What it does: Displays a call-to-action button linking to the church's online giving platform.
Data source: premium_churches.giving_url (text, external URL).
Rendering logic:
IF giving_url exists and is non-empty:
Render section with:
- Heading (family label: "Give Online" / "Support Our Parish" / "Give")
- Brief text encouraging generosity
- Large CTA button linking to giving_url (opens in new tab)
- Button styled with family accent color
ELSE:
Do not render
When it renders: Only when the church has set a giving URL in the admin.
Section 15: Map & Contact Info
What it does: Renders a Leaflet map showing the church's location alongside contact information (phone, email, website, social links).
Data source:
- Location:
churches.latitude,churches.longitude,churches.address - Phone:
churches.phone - Website:
churches.website - Social:
premium_churches.custom_social_media(JSONB) - Email:
premium_churches.contact_email
Rendering logic:
IF latitude and longitude exist:
Render Leaflet map with marker at church location
Map: interactive, zoomable, with OpenStreetMap tiles
Marker popup: church name and address
ELSE:
Show address text only (no map)
Contact info (beside or below map):
- Address (always shown if available)
- Phone (with tel: link for mobile click-to-call)
- Email (with mailto: link)
- Website (external link, opens in new tab)
- Social media icons (Facebook, Instagram, Twitter/X, YouTube, TikTok)
Only icons with URLs are shown
When it renders: Almost always. Most churches have at least an address and phone number from their PewSearch listing. The map renders when coordinates are available.
Section 16: Contact Form
What it does: A form visitors can fill out to contact the church. Submissions are stored in the contact_submissions table and an email notification is sent to the church's contact_email.
Data source: premium_churches.contact_email (submission recipient).
Form fields:
- Name (required)
- Email (required)
- Phone (optional)
- Message (required, textarea)
Rendering logic:
IF contact_email exists:
Render contact form with heading (family label: "Contact Us" / "Contact the Parish" / "Reach Out")
On submit:
- Validate required fields
- POST to /api/contact (or inline server action)
- INSERT into contact_submissions (church_id, name, email, phone, message, created_at)
- Send email notification to contact_email
- Show success message: "Thank you! We'll be in touch soon."
Spam protection: honeypot field + rate limiting
ELSE:
Do not render (no recipient for submissions)
When it renders: When the church has set a contact email. Submissions are also visible in the admin dashboard metrics.
Database table: contact_submissions
| Column | Type | Purpose |
|---|---|---|
id | UUID | Primary key |
church_id | UUID | FK to churches |
name | text | Submitter name |
email | text | Submitter email |
phone | text | Submitter phone (optional) |
message | text | Message body |
created_at | timestamptz | Submission timestamp |
Section 17: ChurchWiseAI Chatbot Widget
What it does: Embeds the ChurchWiseAI chatbot widget as a floating button in the bottom-right corner of the page.
Data source: premium_churches.chatbot_enabled (boolean), premium_churches.chatbot_agent_id (UUID).
Rendering logic:
IF chatbot_enabled === true AND chatbot_agent_id is valid UUID:
Inject config into window:
window.__CWAI_CONFIG = {
churchId: chatbot_agent_id,
color: style.chatbotAccent, // family-specific color
position: "bottom-right"
}
Dynamically load script: https://churchwiseai.com/embed/churchwiseai-widget.js
ELSE:
Do not render
When it renders: Only when both chatbot_enabled is true AND chatbot_agent_id is a valid UUID. This prevents rendering a broken widget.
See Chatbot Integration for full details on the widget, accent colors, and tier restrictions.
Section 18: Footer
What it does: Page footer with social links, contact info, and branding.
Data source: Social links from premium_churches.custom_social_media, contact info from churches.
Rendering logic:
Render footer with:
- Church name
- Address
- Phone (click-to-call)
- Social media icon links (only those with URLs)
- "Powered by PewSearch" attribution (not removable on any Pro Website tier — branding removal is not currently offered for PewSearch products, unlike the CWA chatbot Suite tier which removes the "Powered by ChurchWiseAI" badge)
- Copyright year (dynamic)
Footer styling: dark background (family-specific shade), light text
Full-width, responsive layout
When it renders: Always. Every page has a footer.
Section Visibility Summary
| Section | Always Renders | Data Required |
|---|---|---|
| StickyNav | Yes | -- |
| Demo Badge | Conditional | Demo UUID prefix |
| VideoHero | Yes | -- (uses default video) |
| About | Conditional | churches.description |
| Beliefs & Values | Conditional | premium_churches.beliefs |
| VideoTransition (1st) | Yes | -- |
| Service Times | Conditional | custom_hours or churches.service_times |
| What to Expect | Conditional | premium_churches.what_to_expect (any field) |
| Staff | Conditional | premium_churches.custom_staff |
| VideoTransition (2nd) | Yes | -- |
| Ministries | Conditional | premium_churches.custom_ministries |
| Featured Sermon | Conditional | featured_video_url or sermons[0] |
| Events | Conditional | premium_churches.events (future events) |
| Giving | Conditional | premium_churches.giving_url |
| Map & Contact Info | Conditional | churches.latitude/longitude or address |
| Contact Form | Conditional | premium_churches.contact_email |
| Chatbot Widget | Conditional | chatbot_enabled + valid chatbot_agent_id |
| Footer | Yes | -- |
Always-visible sections (5): StickyNav, VideoHero, VideoTransition (x2), Footer. These ensure every Pro Website page looks complete even with zero admin edits.
Conditional sections (14): Progressively appear as the church adds content.
See Also
- Overview -- product summary, data model, pricing
- Template System -- denomination detection, visual families, style object
- Admin Features -- how churches populate the data that drives these sections
- Chatbot Integration -- Section 17 details