When working with SharePoint development scenarios—especially for automation or site provisioning—it is often necessary to replicate list structures and views. This article demonstrates how to extract the XML of an existing view in SharePoint and use PnPjs to recreate both the list and the associated view programmatically.


How to Retrieve a View’s XML and Clone a SharePoint List and View Using PnPjs

When working with SharePoint development scenarios—especially for automation or site provisioning—it is often necessary to replicate list structures and views. This article demonstrates how to extract the XML of an existing view in SharePoint and use PnPjs to recreate both the list and the associated view programmatically.

Retrieving the View Schema XML

Every view in SharePoint (Classic or Modern) is backed by an XML schema that defines how data is displayed, sorted, filtered, and grouped. To get this XML definition, you must perform a REST call to the _api/web/lists/getbytitle('YourListTitle')/views/getbytitle('YourViewTitle')?$select=ListViewXml.

import { spfi, SPFx } from "@pnp/sp";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/views";

// Setup context
const sp = spfi().using(SPFx(this.context));

// Get XML of the view
const getViewXml = async (listTitle: string, viewTitle: string): Promise<string> => {
  const view = await sp.web.lists.getByTitle(listTitle).views.getByTitle(viewTitle).select("ListViewXml")();
  return view.ListViewXml;
};

This function returns the full schema XML that defines the view layout, columns, and filtering logic.

Creating a New List

You can create a new SharePoint list programmatically using PnPjs like so:

import "@pnp/sp/lists/web";

const createList = async (listTitle: string, templateType: number = 100): Promise<void> => {
  await sp.web.lists.add(listTitle, "Cloned List", templateType);
};

Here, templateType = 100 refers to a standard custom list.

Creating a New View Using the Retrieved XML

Once the list is created and you have the XML from the source view, you can apply it to the new list as follows:

import "@pnp/sp/views/list";

const createViewWithXml = async (listTitle: string, viewXml: string): Promise<void> => {
  await sp.web.lists.getByTitle(listTitle).views.add("Cloned View", false, viewXml);
};

Note:

  • The second parameter (false) disables the view as the default view.
  • You must ensure the fields used in the XML exist in the new list.

Cloning the List Fields (Optional)

To fully replicate a list, including fields, you can enumerate the fields in the source list and recreate them in the destination.

import "@pnp/sp/fields/list";

const cloneFields = async (sourceList: string, targetList: string) => {
  const fields = await sp.web.lists.getByTitle(sourceList).fields();

  for (const field of fields) {
    if (!field.ReadOnlyField && !field.Hidden && !field.Sealed) {
      try {
        await sp.web.lists.getByTitle(targetList).fields.createFieldAsXml(field.SchemaXml);
      } catch (err) {
        console.warn(`Failed to create field ${field.InternalName}:`, err);
      }
    }
  }
};

Full Workflow: Clone List and View

Putting all together:

const cloneListAndView = async (sourceList: string, sourceView: string, targetList: string) => {
  const viewXml = await getViewXml(sourceList, sourceView);
  await createList(targetList);
  await cloneFields(sourceList, targetList);
  await createViewWithXml(targetList, viewXml);
};

This function automates the entire process:

  1. Retrieve view XML.
  2. Create a new list.
  3. Clone all non-hidden, editable fields.
  4. Add the view using the cloned XML.

Technical Considerations

  • Ensure field dependencies (e.g., Lookup fields, Managed Metadata) are handled or excluded.
  • This only clones the view structure, not the list items.
  • You may need elevated permissions to read view schema and create lists or views.

Summary Table

StepFunction/Method UsedNotes
Get View XMLviews.getByTitle().select("ListViewXml")Retrieves full CAML/XML of a view
Create Listlists.add()Creates a blank custom list
Clone Fieldsfields() and createFieldAsXml()Optional: replicates columns
Create View in New Listviews.add(viewTitle, isDefault, viewXml)Adds the view with cloned XML
Full AutomationcloneListAndView()Combines all above into a reusable function

References

This approach can be used to automate site provisioning, enforce consistency across site collections, or build site templates on the fly using modern SPFx solutions.

Edvaldo Guimrães Filho Avatar

Published by