All Articles

Sitecore JSS with Next.js - Edit Frames

In this blog post, I will explain how to create and use an Edit Frame on a JSS component with Next.js.

Edit Frame

EditFrames in the Experience Editor is a feature that you can use to give users front-end access to fields that are not directly accessible, either because they are not visible or they are of a type that are not directly front-end editable.

-Sitecore Documentation

Edit Frames can be used in situations where:

  • You have multilist field, or a dropdown field that you are using in your rendering. As it can’t be editable, you can use Edit Frame to show a pop-up.
  • You use the children items of your datasource item, and would like to control the ordering/editing/deletion from the Experience Editor.

Edit Frame with Sitecore JSS

Sitecore JSS offers an Edit Frame component across every framework it offers.

I will be explaining the usage of the Edit Frame component with Next.js in the further steps.

For the example, I will be creating an Edit Frame which will show the various fields that the item has in a pop-up.

Use the below code in your componet:

import { FunctionComponent } from "react";
import { EditFrame, Link } from '@sitecore-jss/sitecore-jss-nextjs';
import { Icon} from "./icon";

type SubItem {
  id: string;
  fields: {
     SubItemTitle: Field<string>;
     SubItemSubtitle: Field<string>;
     SubItemIcon: IconItem;
     SubItemLink: LinkField;
   }
};
type SampleComponentProps = ComponentProps & {
  fields: {
    title: Field<string>;
    description: Field<string>;
    subItems: SubItem[];
  };
};

const MyComponent: FunctionComponent<SampleComponentProps> = (props) => {
    const editFrameButtons = [
        {
            header: 'FieldEditButton',
            icon: '/~/icon/Office/16x16/pencil.png',
            fields: ['SubItemTitle', 'SubItemSubtitle', 'SubItemIcon', 'SubItemLink'],
            tooltip: 'Edit the sub-item',
        }
    ];

    const getEditFrameProps = (dataSource?: string) => {
        return {
            dataSource: dataSource
                ? {
                    itemId: dataSource,
                }
                : undefined,
            buttons: editFrameButtons,
            title: 'Edit component',
            tooltip: 'Edit component',
            cssClass: '',
        };
    };
    return (
        <>
          <Text field={props.fields.title} />
          <RichText field={props.fields.description} />
           {props.fields.subItems?.map(
             (subItem) => (subItem &&
              <EditFrame {...getEditFrameProps(subItem?.id)}>
                 <Text field={subItem.fields.SubItemTitle} />
                 <Text field={subItem.fields.SubItemSubtitle} />
                 <Icon icon={subItem.fields.SubItemIcon} />
                 <Link icon={subItem.fields.SubItemLink} />
              </EditFrame>
              )
           )}  
        </>
    );
}

export default MyComponent;

This code should create an edit frame around the sub-item, which should look similar to the below snapshot.

1726660419799

Upon clicking edit, a pop-up should open for the fields.

1726660561228

Sitecore JSS offers 2 kinds of Edit Frame buttons:

  • FieldEditButton - Used to edit certain fields of an item. Upon clicking, opens a pop-up with an editor for the fields mentioned.
  • WebEditButton - Used to perform certain operations on the item. Upon clicking, performs the command mentioned.

We can extend the above component to have multiple buttons, with controls to add/move/delete a sub-item using the below code.

Note that sxawebedit:new command can be used only if your solution has SXA.

import { FunctionComponent } from "react";
import { EditFrame, Link } from '@sitecore-jss/sitecore-jss-nextjs';
import { Icon} from "./icon";

type SubItem {
  id: string;
  fields: {
     SubItemTitle: Field<string>;
     SubItemSubtitle: Field<string>;
     SubItemIcon: IconItem;
     SubItemLink: LinkField;
   }
};
type SampleComponentProps = ComponentProps & {
  fields: {
    title: Field<string>;
    description: Field<string>;
    subItems: SubItem[];
  };
};

const MyComponent: FunctionComponent<SampleComponentProps> = (props) => {
    const editFrameButtons = [
        {
            header: 'FieldEditButton',
            icon: '/~/icon/Office/16x16/pencil.png',
            fields: ['SubItemTitle', 'SubItemSubtitle', 'SubItemIcon', 'SubItemLink'],
            tooltip: 'Edit the sub-item',
        },
        {
            header: 'WebEditButton',
            icon: '/~/icon/Office/16x16/navigate_plus.png',
            click: 'sxawebedit:new',
            tooltip: 'Add sub-item',
            parameters: { navigate: "0", child: "0" }
        },
        {
            header: 'WebEditButton',
            icon: '/~/icon/Office/16x16/navigate_up.png',
            click: 'item:moveup',
            tooltip: 'Move up',
        },
        {
            header: 'WebEditButton',
            icon: '/~/icon/Office/16x16/navigate_down.png',
            click: 'item:movedown',
            tooltip: 'Move down',
        },
        {
            header: 'WebEditButton',
            icon: '/~/icon/Office/16x16/delete.png',
            click: 'webedit:delete',
            tooltip: 'Delete sub-item',
        }
    ];

    const getEditFrameProps = (dataSource?: string) => {
        return {
            dataSource: dataSource
                ? {
                    itemId: dataSource,
                }
                : undefined,
            buttons: editFrameButtons,
            title: 'Edit component',
            tooltip: 'Edit component',
            cssClass: '',
        };
    };
    return (
        <>
          <Text field={props.fields.title} />
          <RichText field={props.fields.description} />
           {props.fields.subItems?.map(
             (subItem) => (subItem &&
              <EditFrame {...getEditFrameProps(subItem?.id)}>
                 <Text field={subItem.fields.SubItemTitle} />
                 <Text field={subItem.fields.SubItemSubtitle} />
                 <Icon icon={subItem.fields.SubItemIcon} />
                 <Link icon={subItem.fields.SubItemLink} />
              </EditFrame>
              )
           )}  
        </>
    );
}

export default MyComponent;

You can find my articles on Sitecore JSS here.

Happy Sitecoring!

Published Sep 18, 2024

Sitecore MVP Technology 2024-23. Web Developer with rich experience in Sitecore and ASP.NET MVC.