Skip to main content

Frontend Helpers

qore-next exports frontend helpers from packages/framework/src/system/resources/js/internal.ts.

Prefer these helpers over custom Axios instances or duplicate stores. They keep frontend code aligned with the configuration passed to QoreAppProvider.

API Requests​

Use the Axios instance configured in QoreAppProvider.

import { useQore } from 'qore-next'

function SaveButton() {
const { api } = useQore()

return <button onClick={() => api.post('users', { name: 'Koen' })}>Save</button>
}

addGlobalQoreInterceptors({ app }) sets baseURL to ${app.apiEndpoint}/api and runs registered API error handlers.

registerApiErrorHandler('my-handler', (error) => {
// handle AxiosError
})

Qore Config​

const { app, api, screens, frontendUrl } = useQore()
  • app: the QoreApp config from resources/js/app.tsx.
  • api: Axios instance.
  • screens: Ant Design breakpoints.
  • frontendUrl(path): applies frontendUrlPrefix.

The app logo defaults to /img/logo.svg and /img/logo-dark.svg. Override the logo file in QoreAppProvider when an app ships differently named assets or a non-SVG format:

<QoreAppProvider
app={{
// ...
logo: ({ darkMode }) => (darkMode ? 'acme-logo-dark.png' : 'acme-logo.png')
}}
/>

Qore resolves the returned file to ${app.apiEndpoint}/img/{file}.

Auth​

const { me, resources, getResource, hasPermission, hasPermissions } = useAuth()

Use useAuthStore() only when you need raw auth store state:

const user = useAuthStore((state) => state.user)
const isAuthenticated = useAuthStore((state) => state.isAuthenticated)

Globals Store​

const resources = useGlobalStore((state) => state.resources)
const preferences = useGlobalStore((state) => state.preferences)
const modules = useGlobalStore((state) => state.modules)
const isBroadcastingEnabled = useGlobalStore((state) => state.isBroadcastingEnabled)

Globals are fetched by useAppGlobals() from me and globals, then stored in useAuthStore and useGlobalStore.

Layout Store​

const darkMode = useLayoutStore((state) => state.darkMode)
const setDarkMode = useLayoutStore((state) => state.setDarkMode)
const setSiderCollapsed = useLayoutStore((state) => state.setSiderCollapsed)

The layout store also writes CSS variables for theme colors.

Node Helpers​

Inside rendered node components:

const { nodeData, reloadNode, isNodeLoading } = useNodeQuery()
const { nodeState, setNodeState, removeNodeState } = useNodeState()
const { onEvent, onFormSuccess, reloadExternalNode } = useNodeActions()

Use these only inside NodeProvider.

Root <Node> requests use the React Query cache by default. Disable it for form-backed endpoints when an old response should not be reused while the new request loads:

<Node endpoint='profile-page' hasQueryCache={false} />

When the initial request fails, <Node> displays a translated error result with a retry button. Override the complete fallback when a page needs different content:

<Node
endpoint='profile-page'
errorFallback={<Alert type='error' title='Profile could not be loaded' />}
/>

Form Helpers​

Inside field or form components:

const { mappedFields, setFieldValue, getValues, formStatus } = useFormNode()

For normal field inputs:

const { inputAttributes, setValue, localValue } = useFieldForm(field)

Registration​

registerField({ name, form, detail, index, filter })
registerNode({ name, node })
registerIcons({ user: User })

Formatting​

const {
formatDate,
formatDateTime,
formatRelativeTime,
formatCurrency,
formatNumber
} = useFormatter()

Formatting uses language/locale preferences from globals.

Utilities​

  • cn(...classes): clsx + tailwind-merge.
  • truncate(text, maxLength = 16).
  • frontendUrl(path, prefix).
  • getPathWithoutFrontendPrefix(path, prefix).
  • isEmpty(value).