How-to Guides


This section provides practical, step-by-step guides for completing common tasks and implementing specific workflows using the library's components. Each guide is designed to be a self-contained set of instructions to help you achieve a specific outcome efficiently.


How to Add Custom Elements to the Header#

The Header component is designed to be extensible. You can add custom buttons, search bars, or other React components directly into the header by leveraging the addons prop.

Goal#

To add a custom "Chat" button, a search input, and additional action icons to the main application header.

Prerequisites#

  • A functional React application with the @arcblock/ux library installed.
  • An existing <Header> component instance. For more information, see the Header component documentation.

Steps#

The addons prop accepts a render function. This function receives the default addons (like the session manager) as its first argument, allowing you to decide where to place your custom elements relative to the defaults.

  1. Define the addons Render Prop
    In your Header component, pass a function to the addons prop. This function should return the JSX you want to render.
    <Header
      meta={meta}
      addons={(defaultAddons, { navigation }) => {
        // Your custom components will go here
        return (
          <>
            {/* Render your custom components */}
            {defaultAddons}
          </>
        );
      }}
    />
  2. Add Custom Components
    Inside the render function, you can add any components you need. In this example, we'll add a standard Material-UI Button, a few AddonButton components for icons, and a Divider.
  3. Combine with Default Addons
    It is standard practice to render the defaultAddons that are passed into the function. This ensures that essential elements like the locale switcher and session manager are still displayed. You can place your custom components before or after the defaultAddons.

Complete Example#

Here is a complete example demonstrating how to add several custom elements to the header. This includes navigation, buttons, and icons, rendered alongside the default session manager.

How to Add Custom Elements to the Header

import { Box, Divider, Button } from '@mui/material';
import { SessionContext } from '@arcblock/did-connect-react/lib/Session';
import { AddonButton } from '@arcblock/ux/lib/Header/addon-button';
import NavMenu from '@arcblock/ux/lib/NavMenu';
import SessionManager from '@arcblock/ux/lib/SessionManager';
import Header from '@arcblock/ux/lib/Header';
import { Icon } from '@iconify/react';

// Mock data for demonstration purposes
const mockBlockletMeta = {
  title: 'My App',
  description: 'A great application',
  logoUrl: 'https://www.arcblock.io/image-bin/uploads/eb1cf5d60cd85c42362920c49e3768cb.svg'
};

const mockSessionContextValue = {
  session: {
    user: {
      fullName: 'Demo User',
      did: 'z1ex...',
      role: 'admin',
    },
    // ... other session properties
  },
};

See all 39 lines

How to Handle Optional Component Dependencies#

Many blocklets rely on other components to provide specific features. The ComponentInstaller allows you to build features that depend on optional components, and if they are not installed, it provides a user-friendly way for an administrator to install them.

Goal#

To protect a feature that requires another blocklet component to be installed. If the component is missing, an administrator will be shown an interface to install it, while other users will see nothing.

Prerequisites#

  • A feature in your application that depends on another component (e.g., a "Media Manager" that requires the "Media Kit" blocklet).
  • The DID of the component dependency.
  • Familiarity with user roles (owner, admin).

Steps#

  1. Import ComponentInstaller
    First, import the component from the library.
    import ComponentInstaller from '@arcblock/ux/lib/ComponentInstaller';
  2. Wrap Your Feature
    Wrap the component or feature that has the dependency with the ComponentInstaller.
  3. Provide the Component DID
    Pass the DID of the required component to the did prop. This can be a single string or an array of strings if there are multiple dependencies.
  4. Configure Behavior for Non-Admins
    Use the noPermissionMute prop. When set to true, users who do not have permission to install components (i.e., non-admins) will not see the installation prompt. You can provide a fallback component to show them instead.

Complete Example#

In this scenario, we have a MyFeatureButton that should only be rendered if the component with DID z8ia... is installed.

How to Handle Optional Component Dependencies

import ComponentInstaller from '@arcblock/ux/lib/ComponentInstaller';
import { Button } from '@mui/material';

const REQUIRED_COMPONENT_DID = 'z8ia1mAXo8ZE7ytGF36L5uBf9kD2kenhqFGp9'; // Example DID

// This is the component that requires the dependency
function MyFeatureButton() {
  return <Button variant="contained">Use Awesome Feature</Button>;
}

export default function OptionalComponentGuide() {
  return (
    <ComponentInstaller
      // The DID of the component to check for
      did={REQUIRED_COMPONENT_DID}
      // A list of roles that are allowed to see the installer UI
      roles={['owner', 'admin']}
      // If true, non-admins will not see the installer UI
      noPermissionMute
      // Optional: What to show non-admins if the component is not installed
      fallback={<div>This feature is not available.</div>}
      // A callback that fires after a successful installation
      onInstalled={() => console.log('Component was installed successfully!')}
    >
      {/* This child will only be rendered if the component is already installed */}

See all 4 lines

When an admin visits this page and the component is not installed, they will see a pop-up allowing them to install it. A regular user will see the fallback message. Once installed, all users will see the MyFeatureButton.


How to Implement Real-time User Notifications#

You can provide users with real-time feedback and notifications by listening to WebSocket events from the Blocklet Server. The NotificationAddon component is a ready-to-use solution for displaying an unread notification count in the header.

Goal#

To add a notification bell icon to the application header that displays a badge with the count of unread notifications and updates in real-time.

Prerequisites#

  • Your blocklet must be running on a Blocklet Server version that supports the notification service (1.16.42 or higher).
  • A <Header> component where the notification icon will be placed.
  • A session context providing user information.

Key Concepts#

  • WebSocket Events: The Blocklet Server broadcasts events when notifications are created or read.
  • useListenWsClient: A hook to get a WebSocket client instance for a specific channel (e.g., 'user').
  • Event Naming: Events are scoped to the user and blocklet. The format for new notifications is ${blocklet.did}/${user.did}/notification:blocklet:create.

Steps#

The NotificationAddon component encapsulates all the required logic for listening to WebSocket events and displaying the unread count.

  1. Import NotificationAddon
    import NotificationAddon from '@arcblock/ux/lib/common/notification-addon';
  2. Add to Header addons
    The simplest way to use this is to add it inside the Header's addons render prop.
  3. Pass the Session Object
    The NotificationAddon component requires the session object to identify the current user and manage the unread count state.

Complete Example#

This example shows how to integrate the NotificationAddon into the Header. It will automatically connect to the WebSocket, listen for events, and update the badge count.

How to Implement Real-time User Notifications

import { SessionContext } from '@arcblock/did-connect-react/lib/Session';
import Header from '@arcblock/ux/lib/Header';
import NotificationAddon from '@arcblock/ux/lib/common/notification-addon';

// Mock data for demonstration purposes
const mockBlockletMeta = {
  title: 'My App',
  description: 'A great application',
  logoUrl: 'https://www.arcblock.io/image-bin/uploads/eb1cf5d60cd85c42362920c49e3768cb.svg'
};

const mockSessionContextValue = {
  session: {
    user: {
      fullName: 'Demo User',
      did: 'z1ex...',
      role: 'admin',
    },
    unReadCount: 3, // Initial unread count
    setUnReadCount: () => {}, // State setter function
    // ... other session properties
  },
};

export default function NotificationGuide() {

See all 17 lines

When a new notification for the logged-in user is created, the badge count on the bell icon will automatically increment. Clicking the icon will navigate the user to their notifications page.


How to Publish Resources with BlockletStudio#

The BlockletStudio component provides a complete, embeddable UI for publishing resources and components. It handles user connection, resource selection, and the release process, simplifying a complex workflow into a single component.

Goal#

To add a button that opens a dialog, allowing users to select and publish files and dependent components from the blocklet.

Prerequisites#

  • An API endpoint in your blocklet that returns a list of available resources.
  • The DID of the component that provides the publishing UI (the "studio" component).

Steps#

  1. Import BlockletStudio and Manage State
    You'll need to manage the visibility of the studio dialog using component state.
    import { useState } from 'react';
    import { BlockletStudio } from '@arcblock/ux/lib/BlockletStudio';
    import { Button, CircularProgress } from '@mui/material';
  2. Render the Component
    Place the <BlockletStudio /> component in your app and control its visibility with the open and setOpen props.
  3. Configure Essential Props
    • componentDid: The DID of the studio blocklet that provides the publishing service.
    • title, description: Metadata for the item being published.
    • resourcesParams: An object passed as query parameters to your resource-fetching API.
    • components: An array of components to be pre-selected or required.
    • resources: An object specifying which resources to pre-select.
  4. Handle Lifecycle Events
    Use the onOpened, onUploaded, and onReleased callbacks to respond to events in the publishing lifecycle, such as hiding a loading spinner or showing a success message.

Complete Example#

This example shows a button that, when clicked, opens the BlockletStudio dialog. It also demonstrates managing a loading state for a better user experience.

How to Publish Resources with BlockletStudio

import { useState } from 'react';
import { Button, CircularProgress } from '@mui/material';
import { BlockletStudio } from '@arcblock/ux/lib/BlockletStudio';

// The DID of the blocklet that provides the studio/publishing UI
const AI_STUDIO_COMPONENT_DID = 'z8ia1mAXo8ZE7ytGF36L5uBf9kD2kenhqFGp9'; // Example DID

export default function PublisherGuide() {
  const [isStudioOpen, setStudioOpen] = useState(false);
  const [isOpening, setOpening] = useState(false);

  const handleShowDialog = () => {
    setOpening(true);
    setStudioOpen(true);
  };

  return (
    <>
      <Button
        variant="contained"
        onClick={handleShowDialog}
        disabled={isOpening}
        startIcon={isOpening ? <CircularProgress size={16} /> : null}>
        Publish to Studio
      </Button>

See all 36 lines