npm.io
0.1.6 • Published 4h ago

@axcode/axcloud-sdk

Licence
SEE LICENSE IN LICENSE.md
Version
0.1.6
Deps
2
Size
458 kB
Vulns
0
Weekly
0

@axcode/axcloud-sdk

SDK for building websites with AxCloud CMS and member management.

Installation

npm install @axcode/axcloud-sdk

Version 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'), and useContent('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:

  1. API Key (apiKey prop): 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
  2. 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.

Keywords