Skip to Content
ReferenceAvailable Hooks & Context

Available Hooks & Context

Gymlium provides React hooks that give your template components access to platform data, authentication state, and utility functions. These hooks are the primary way your template interacts with the platform — you never need to fetch data directly.

useApp()

The main hook for accessing application-level data and utilities. Available in every component.

import { useApp } from '@/hooks/useApp' export default function HomeContent() { const { locale, isRtl, t, localePath, clientName, locales, plan, planLimits, stats, registrationOpen, } = useApp() return ( <main> <h1>{t('welcomeTo')} {clientName}</h1> </main> ) }

Return values

PropertyTypeDescription
localestringCurrent active locale code (e.g. "en", "ar", "fr")
isRtlbooleantrue when the current locale is a right-to-left language (Arabic, Persian)
t(key: string) => stringTranslation function — returns the translated string for the given key
localePath(path: string) => stringPrefixes a path with the current locale (e.g. localePath('/about') → "/en/about")
clientNamestringThe trainer’s business name as configured in their dashboard
localesstring[]Array of locale codes enabled for this trainer’s site
planstringThe trainer’s subscription plan (e.g. "starter", "professional", "elite")
planLimitsPlanLimitsFeature limits based on the trainer’s plan (see below)
statsSiteStatsSite-level statistics (see below)
registrationOpenbooleanWhether client registration is currently enabled

PlanLimits object

interface PlanLimits { maxPages: number // Maximum number of enabled pages maxBlogPosts: number // Maximum blog posts (-1 = unlimited) maxClients: number // Maximum registered clients hasScheduling: boolean // Whether scheduling feature is available hasEvents: boolean // Whether events feature is available hasBlog: boolean // Whether blog feature is available }

Use planLimits to conditionally show or hide sections. For example, don’t render a “Blog” nav link if planLimits.hasBlog is false:

const { planLimits, localePath, t } = useApp() return ( <nav> <a href={localePath('/')}>{t('home')}</a> <a href={localePath('/about')}>{t('about')}</a> {planLimits.hasBlog && ( <a href={localePath('/blog')}>{t('blog')}</a> )} {planLimits.hasScheduling && ( <a href={localePath('/schedule')}>{t('schedule')}</a> )} </nav> )

SiteStats object

interface SiteStats { postCount: number // Number of published blog posts serviceCount: number // Number of active services testimonialCount: number // Number of approved testimonials eventCount: number // Number of upcoming events transformationCount: number // Number of transformation entries }

Use stats to decide whether to render empty-state messages or hide sections entirely:

const { stats, t } = useApp() {stats.testimonialCount > 0 ? ( <TestimonialCarousel /> ) : ( <p>{t('noTestimonialsYet')}</p> )}

useAuth()

Provides the current authentication state. Use this to show login/logout controls, protect pages, and display user-specific content.

import { useAuth } from '@/hooks/useAuth' export function Header() { const { user, loading, isAdmin, signOut } = useAuth() if (loading) return null return ( <div> {user ? ( <> <span>{user.displayName}</span> {isAdmin && <a href="/dashboard">Dashboard</a>} <button onClick={signOut}>Sign out</button> </> ) : ( <a href="/login">Sign in</a> )} </div> ) }

Return values

PropertyTypeDescription
userUser | nullCurrent user object, or null if not authenticated
loadingbooleantrue while auth state is being resolved
isAdminbooleantrue if the current user is the trainer (site owner)
signOut() => Promise<void>Signs the user out and redirects to the home page

User object

interface User { id: string email: string displayName: string photoURL: string | null role: 'admin' | 'client' }

Always check loading before making assumptions about user. During initial page load, user is null and loading is true — this doesn’t mean the visitor is unauthenticated.

useRouter()

The standard Next.js router hook from next/navigation. Use it for programmatic navigation.

import { useRouter } from 'next/navigation' import { useApp } from '@/hooks/useApp' export default function LoginContent() { const router = useRouter() const { localePath } = useApp() function handleLoginSuccess() { router.push(localePath('/account')) } return <div>{/* login form */}</div> }

Always wrap paths with localePath() when using router.push() or router.replace() to ensure locale-aware navigation.

Hook usage rules

  1. Hooks can only be called inside React components or other hooks — standard React rules apply
  2. useApp() and useAuth() are available everywhere — the platform wraps your template in the necessary context providers
  3. Don’t destructure more than you need — for performance, only pull the values your component actually uses
  4. t() always returns a string — if the key doesn’t exist, it returns the key itself as a fallback
  5. localePath() handles the root path — localePath('/') correctly returns "/en" (not "/en/")
Last updated on