Sana Assistant (online)
Table of Contents

Content Blocks

Web store

The contentBlocks object is a supported web store named export that Sana expects an add-on to provide from its entry JavaScript module.

The contentBlocks object is a record whose keys are content block identifiers defined on the server, and whose values are React components responsible for rendering the corresponding content blocks in the web store.

The contentBlocks object has the following signature:

contentBlocks?: Record<string, ContentBlock>;
Important

The key in the contentBlocks object must match the content block identifiers defined using the ContentBlockIdAttribute in the extension classes on the server.

ContentBlock component

The ContentBlock<M> component takes as a parameter an object with props of type ContentBlockProps<M>, where M is a generic type representing the specific content block model, defaulting to any if no custom model is provided.

The ContentBlockProps<M> type contains the following properties:

Property Type Description
id string Content block unique identifier.
isDesignerMode boolean | undefined Specifies if visual designer mode is activated.
model M Content block data model.
fullWidthRow boolean Specifies if content block parent row occupies full viewport width.
bounds { sm: ColumnCount; md: ColumnCount; lg: ColumnCount } Specifies amount of columns in 12-column grid layout occupied by content block parent column.
styleWrapperProps { horizontalAlignment: HorizontalAlignment } Styles related props that can be passed to container HTML element that wraps content block.

The bounds object contains the following properties:

Property Type Description
sm ColumnCount Number of columns on devices with small screen.
md ColumnCount Number of columns on devices with medium screen.
lg ColumnCount Number of columns on devices with large and subsequent screens.

ColumnCount is a union type that represents the number of columns in a 12-column grid layout and has the following definition:

type ColumnCount = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;

The styleWrapperProps object contains the following properties:

Property Type Description
horizontalAlignment HorizontalAlignment Content block text horizontal alignment.

HorizontalAlignment is a union type that represents the horizontal alignment modes and has the following definition:

type HorizontalAlignment = 'LEFT' | 'CENTER' | 'RIGHT' | 'JUSTIFY';

Server-Side Rendering Support

Content blocks can optionally provide server-side rendering (SSR) support to preload data during the server rendering process.

For detailed information about implementing server-side rendering for content blocks, including type definitions, examples, see Server-Side Rendering.

Example

import { memo } from 'react';
import { DomHead, DomElement, DomBody } from 'sana/elements';

type Props = {
  model?: {
    codeContent: string | null;
    headContent: string | null;
    bodyEndContent: string | null;
  };
};

const Code = ({ model }: Props) => {
  if (!model)
    return null;

  const { codeContent, headContent, bodyEndContent } = model;
  if (!codeContent && !headContent && !bodyEndContent)
    return null;

  return (
    <>
      {headContent && <DomHead content={headContent} />}
      {codeContent && <DomElement content={codeContent} />}
      {bodyEndContent && <DomBody content={bodyEndContent} />}
    </>
  );
};

export default memo(Code);

Admin

The contentBlocks object is a supported admin named export that Sana expects an add-on to provide from its entry JavaScript module.

The contentBlocks object is a record whose keys are content block identifiers defined on the server, and whose values are ContentBlock<M> objects that define how each block can be configured in Sana Admin.

The contentBlocks object has the following signature:

contentBlocks?: Record<string, ContentBlock>;
Important

The key in the contentBlocks object must match the content block identifiers defined using the ContentBlockIdAttribute in the extension classes on the server.

This one looks the same as for the web store, but internally it's a different contract. The ContentBlock<M> type contains the following properties:

Property Type Description
editor (optional) ModelEditor<M> The React component used to edit the content block model.
translator (optional) ModelTranslator<M> The React component used to translate the content block model.
logoUrl (optional) string A path or URL to the content block logo shown in the Sana Admin content block explorer.
defaultSettings (optional) Partial<ContentBlockVisualSettings> Default visual settings applied to the content block.

If the translator property is omitted, the content block is considered to be non-translatable.

The ContentBlockVisualSettings type contains the following properties:

Property Type Description
minDesktopHeight string Minimum height of the content block on desktop devices.
minTabletHeight string Minimum height of the content block on tablet devices.
minMobileHeight string Minimum height of the content block on mobile devices.
minDesktopWidth string Minimum width of the content block on desktop devices.
minTabletWidth string Minimum width of the content block on tablet devices.
minMobileWidth string Minimum width of the content block on mobile devices.
stretchHeight boolean Determines whether the content block should stretch to fill available vertical space.
stretchWidth boolean Determines whether the content block should stretch to fill available horizontal space.
margin string Margin.
padding string Padding.
horizontalAlignment 'LEFT' | 'CENTER' | 'RIGHT' | 'JUSTIFY' Content block horizontal alignment.
verticalSelfAlignment 'INHERITED' | 'TOP' | 'MIDDLE' | 'BOTTOM' | 'JUSTIFY' Content block vertical alignment relative to neighboring elements.

ModelEditor component

The ModelEditor<M> component is a React component used to edit the content block model properties in Sana Admin. It takes as a parameter an object with props of type ModelEditorProps<M>, where M is a generic type representing the specific content block model, defaulting to any if no custom model is provided.

The ModelEditorProps<M> type contains the following properties:

Property Type Description
initialModel M The initial content block model.
onChange (event: ModelChangedEvent) => void The callback called when the model changes.

The ModelChangedEvent<M> type contains the following properties:

Property Type Description
model M | undefined The model.
valid boolean | undefined Indicates whether the model is valid.
dirty boolean | undefined Indicates whether the model has been changed from its initial state.

Example:

import type { ModelEditorProps } from 'sana/types';
import {
  Form,
  FormGroup,
  TextAreaField,
} from 'sana/forms';
import { useResourceTexts } from 'sana/texts';

type Model = {
  headContent: string | null;
  codeContent: string | null;
  bodyEndContent: string | null;
};

const CodeEditor = ({ initialModel, onChange }: ModelEditorProps<Model>) => {
  const texts = useResourceTexts();

  return (
    <Form initialModel={initialModel} onChange={onChange}>
      <FormGroup>
        <TextAreaField name="headContent" label={texts.HeadContent} codeView />
      </FormGroup>
      <FormGroup>
        <TextAreaField name="codeContent" label={texts.CodeContent} codeView />
      </FormGroup>
      <FormGroup>
        <TextAreaField name="bodyEndContent" label={texts.BodyEndContent} codeView />
      </FormGroup>
    </Form>
  );
};

export default CodeEditor;

ModelTranslator component

The ModelTranslator<M> component is a React component used to translate the content block model properties in Sana Admin. It takes as a parameter an object with props of type ModelTranslatorProps<M>, where M is a generic type representing the specific content block model, defaulting to any if no custom model is provided.

The ModelTranslatorProps<M> type contains the following properties:

Property Type Description
initialModel Partial<M> | undefined The initial content block model.
onChange (event: ModelChangedEvent<Partial<M>>) => void The callback called when the model changes.
language TranslationLanguage The language being translated to.
defaultModel M The default content block model.
defaultLanguage TranslationLanguage The default language.

The TranslationLanguage type contains the following properties:

Property Type Description
id number The unique language identifier.
title string The language title.

Example:

import type { ModelTranslatorProps } from 'sana/types';
import { Row, Col } from 'sana/elements';
import {
  Form,
  FormGroup,
  TextArea,
  TextAreaField,
} from 'sana/forms';
import { useResourceTexts } from 'sana/texts';

type Model = {
  headContent: string | null;
  codeContent: string | null;
  bodyEndContent: string | null;
};

const CodeTranslator = ({ initialModel, language, defaultModel, defaultLanguage, onChange }: ModelTranslatorProps<Model>) => {
  const texts = useResourceTexts();

  return (
    <Form initialModel={initialModel} onChange={onChange}>
      <Row>
        <Col>
          <h5>{defaultLanguage.title}</h5>
        </Col>
        <Col>
          <h5>{language.title}</h5>
        </Col>
      </Row>
      <FormGroup>
        <Row>
          <Col>
            <TextArea name="headContentDefault" label={texts.HeadContent} value={defaultModel.headContent} readOnly codeView />
          </Col>
          <Col>
            <TextAreaField name="headContent" label={texts.HeadContent} codeView />
          </Col>
        </Row>
      </FormGroup>
      <FormGroup>
        <Row>
          <Col>
            <TextArea name="codeContentDefault" label={texts.CodeContent} value={defaultModel.codeContent} readOnly codeView />
          </Col>
          <Col>
            <TextAreaField name="codeContent" label={texts.CodeContent} codeView />
          </Col>
        </Row>
      </FormGroup>
      <FormGroup>
        <Row>
          <Col>
            <TextArea name="bodyEndContentDefault" label={texts.BodyEndContent} value={defaultModel.bodyEndContent} readOnly codeView />
          </Col>
          <Col>
            <TextAreaField name="bodyEndContent" label={texts.BodyEndContent} codeView />
          </Col>
        </Row>
      </FormGroup>
    </Form>
  );
};

export default CodeTranslator;

"Generic UI" feature

If a content block does not provide a custom editor or translator, or the Sana Admin client bundle is missing, Sana will render a generic form UI. This UI is generated based on the System.ComponentModel.Annotations applied to the .NET content block model on the server.

The "generic UI" feature works for both the editor and translator parts and is especially useful for simple models with one-level properties, helping to reduce implementation time.

Note

The "generic UI" feature is available only in Sana Admin and is not supported for any of the web store components.