@axcode/axcloud-sdk
SDK for building websites with AxCloud CMS and member management.
Installation
npm install @axcode/axcloud-sdkVersion Tags
The SDK is published with two tags for different environments:
| Tag | Purpose | Stability | Install |
|---|---|---|---|
latest |
Production | Stable, tested | npm install @axcode/axcloud-sdk |
next |
Development/Staging | Preview, may have breaking changes | npm install @axcode/axcloud-sdk@next |
Recommended setup:
// Production project (package.json)
{
"dependencies": {
"@axcode/axcloud-sdk": "^0.1.0"
}
}
// Development/Staging project (package.json)
{
"dependencies": {
"@axcode/axcloud-sdk": "next"
}
}This allows you to test new SDK features in your staging environment before they reach production.
Quick Start
1. Wrap your app with AxCloudProvider
import { AxCloudProvider } from '@axcode/axcloud-sdk'
function App() {
return (
<AxCloudProvider
orgId="org_ba81807b" // Your organization ID
apiUrl="https://api.axcloud.app"
apiKey="pk_live_..." // Public API key from Settings → API Keys
auth0={{
domain: "auth.axcloud.app",
clientId: "your-client-id",
redirectUri: window.location.origin
}}
>
<Router>
<Routes />
</Router>
</AxCloudProvider>
)
}2. Fetch content
import { useNews } from '@axcode/axcloud-sdk'
function NewsPage() {
const { data: news, isLoading, isError } = useNews()
if (isLoading) return <Spinner />
if (isError) return <Error />
return (
<ul>
{news.map(item => (
<li key={item.id}>{item.title}</li>
))}
</ul>
)
}Content visibility: When the user is authenticated,
useNews,useContent('pages'), anduseContent('events')automatically fetch public + internal + members-only content based on the user's organization membership. For anonymous users, only public content is returned.
Pages can be stored once in AxCloud with translations and requested per language:
import { useContentItem } from '@axcode/axcloud-sdk'
function AboutPage({ locale }: { locale: 'sv' | 'en' }) {
const { data: page } = useContentItem('pages', 'about-us', {
lang: locale,
publicOnly: true,
})
return <h1>{page?.title}</h1>
}3. Add authentication
import { useAuth, LoginButton, LogoutButton, ProtectedRoute } from '@axcode/axcloud-sdk'
function Header() {
const { isAuthenticated, user } = useAuth()
return (
<header>
{isAuthenticated ? (
<>
<span>Welcome, {user.name}</span>
<LogoutButton />
</>
) : (
<LoginButton>Sign In</LoginButton>
)}
</header>
)
}
function MemberArea() {
return (
<ProtectedRoute>
<MemberContent />
</ProtectedRoute>
)
}4. Use sections
import { useMySection } from '@axcode/axcloud-sdk'
function MySectionPage() {
const { section, members, isLoading } = useMySection()
if (isLoading) return <Spinner />
if (!section) return <p>You are not assigned to a section</p>
return (
<div>
<h1>{section.name}</h1>
<h2>Members ({members.length})</h2>
<ul>
{members.map(m => <li key={m.id}>{m.name}</li>)}
</ul>
</div>
)
}4b. Filter content by section
import { useNews, useMySection } from '@axcode/axcloud-sdk'
function SectionNews() {
const { sectionId } = useMySection()
// Fetch news for user's section only
const { data: sectionNews } = useNews({ sectionId })
// Or fetch all organization news
const { data: allNews } = useNews()
return (
<div>
<h2>Section News</h2>
{sectionNews.map(item => <NewsCard key={item.id} item={item} />)}
<h2>All Organization News</h2>
{allNews.map(item => <NewsCard key={item.id} item={item} />)}
</div>
)
}5. Fetch organization branding and media
import { useBranding, useLogo, useMedia } from '@axcode/axcloud-sdk'
function Header() {
const { logoUrl, branding, organizationName } = useBranding()
return (
<header style={{ backgroundColor: branding?.primaryColor }}>
{logoUrl && <img src={logoUrl} alt={organizationName} />}
<h1>{organizationName}</h1>
</header>
)
}
// Or just the logo
function Logo() {
const { logoUrl, isLoading } = useLogo()
if (isLoading) return <Skeleton />
return logoUrl ? <img src={logoUrl} alt="Logo" /> : <DefaultLogo />
}
// Fetch specific media file
function HeroImage() {
const { mediaUrl } = useMedia('hero-banner.jpg')
return mediaUrl ? <img src={mediaUrl} alt="Hero" /> : null
}Note: Media URLs are signed S3 URLs that expire after 1 hour. The SDK automatically refreshes them before expiry (staleTime: 30 min).
6. Gate features by module
import { ModuleGate, useOrg } from '@axcode/axcloud-sdk'
function Dashboard() {
const { hasModule } = useOrg()
return (
<div>
<NewsSection />
<ModuleGate module="training" fallback={<UpgradePrompt />}>
<TrainingSection />
</ModuleGate>
{hasModule('ai') && <AIChatWidget />}
</div>
)
}API Reference
Provider
| Component | Description |
|---|---|
AxCloudProvider |
Main provider that combines Auth0, React Query, and SDK context |
Hooks
| Hook | Description |
|---|---|
useAuth() |
Login/logout with Auth0 Universal Login |
useUser() |
Fetch current user with role and permissions |
useOrg() |
Fetch organization info and check modules |
useNews(options?) |
Fetch news articles. Returns public + internal + members content when authenticated. |
useContent(type, options?) |
Fetch any content type. For pages and events, returns member content when authenticated. |
useMySection() |
Fetch current user's section with members |
useSections() |
Fetch all organization sections |
useBranding() |
Fetch organization branding (logo, colors) |
useLogo() |
Fetch organization logo URL |
useMedia(mediaId) |
Fetch specific media file URL |
useAvatar(userId) |
Fetch user avatar URL |
useMediaList(type) |
List media files |
Content Query Options
interface ContentQueryOptions {
page?: number // Page number (default: 1)
pageSize?: number // Items per page (default: 20)
status?: 'draft' | 'published' | 'archived'
visibility?: 'draft' | 'published' | 'archived'
audience?: 'public' | 'internal' | 'members' | 'section'
sectionId?: string // Filter by specific section
search?: string // Search in title/content
sortBy?: string // Sort field (default: 'createdAt')
sortOrder?: 'asc' | 'desc'
lang?: string // Return translated title/slug/blocks when available
publicOnly?: boolean // Force public endpoint even when authenticated
}Components
| Component | Description |
|---|---|
<LoginButton> |
Trigger Auth0 login |
<LogoutButton> |
Trigger logout |
<ProtectedRoute> |
Require authentication to view content |
<ModuleGate> |
Conditionally render based on enabled modules |
Advanced Usage
Custom API calls
import { useAuth } from '@axcode/axcloud-sdk'
function MyComponent() {
const { getAccessToken } = useAuth()
const fetchCustomData = async () => {
const token = await getAccessToken()
const response = await fetch('/api/custom', {
headers: { Authorization: `Bearer ${token}` }
})
return response.json()
}
}Access the underlying Auth0 client
const { getAuth0Client } = useAuth()
const auth0 = getAuth0Client()
// Full Auth0 API available
await auth0.getAccessTokenSilently()
await auth0.getIdTokenClaims()Security Model
API Key vs Authentication Token
The SDK uses two types of credentials:
API Key (
apiKeyprop): A public identifier for your organization- Safe to include in client-side code
- Used for public content endpoints
- Backend validates and rate-limits based on API key
- Without a valid API key, requests return 401
Authentication Token (via Auth0): A secret JWT token
- Automatically managed by the SDK
- Required for member-only content and user data
- Never exposed in client code
What the API Key Protects
| Without API Key | With API Key | With Auth Token |
|---|---|---|
| Nothing | Public news/content | Member content |
| Organization branding | User profile | |
| Public media | Linked accounts | |
| Admin functions |
Endpoint Security
| Endpoint Type | Authentication | Example |
|---|---|---|
| Public content | API key (x-api-key header) | /content/public/{orgId}/news |
| Member content | JWT Bearer token | /content/members/{orgId}/news |
| User data | JWT Bearer token | /api/users/me |
| Admin | JWT Bearer token + role | /api/admin/forms/submissions |
Error Handling
import { useNews, isAxCloudError } from '@axcode/axcloud-sdk'
function NewsPage() {
const { data, error, isError } = useNews()
if (isError) {
if (isAxCloudError(error)) {
switch (error.code) {
case 'UNAUTHORIZED':
return <LoginPrompt />
case 'NOT_FOUND':
return <NotFound />
default:
return <Error message={error.message} />
}
}
return <Error message="Something went wrong" />
}
return <NewsList items={data} />
}License
UNLICENSED - Internal use only. Contact Axcode AB for access.