I am working on a sort of app store, where a modaldialog pops up and shows a list of web parts that can be added to the page. The real issue is when I want to add a web part to the page; the AddWebPart method requires a ZoneID, but as far as I can tell there is absolutely no easy way to get access to the available zones on a page.

I came up with the following:

  • Get the SPWebPartManager and go through its zones The SPWebPartManager requires a Web.UI.Page and I am in a modal dialog so I can't access it. Some sources speak of a .Parent property for the LimitedWebPartManager but that doesn't appear to be available in SP2010
  • Read the html SharePoint has a style tag in the head which contains one line per web part zone. I can access this and extract the ids of the zones... BUT this gets me every zone. Not just the ones that are editable. For example, it also gives me the zone that contains the search box at the top of the page.
  • Read the source of the page I would have to read in the .aspx page from the hive and regex my way through it. This would work, but frankly it's completely absurd to do this.

2 Answers 2


I think you can achieve the task if you manipulate GetZoneID method of SPLimitedWebPartManager

  • How so? AFAIK that method only returns you the zoneid of a certain given web part. Commented Nov 22, 2012 at 13:55
  • 1
    SPLimitedWebPartManager.WebParts will give u a webpartcollection, and enumerating over the collection you can find out the available zone ids, you can give it a try
    – Diptarag
    Commented Nov 22, 2012 at 13:58
  • That's handy, but what about empty zones? Commented Nov 22, 2012 at 14:07

This is an old question but the issue still exists :/

I solved this issue by fetching HTML from page in edit mode and parse the zones.

A hack indeed... but so is SP.

const pageURL = `${_spPageContextInfo.serverRequestPath}?ToolPaneView=2&pagemode=edit`;
fetch(pageURL).then(response => {
    return response.text();
}).then(html => {
    const matches = html.matchAll(/zoneID="(.+?)".*?zoneTitle="(.+?)"/g);
    const zones = [...matches].reduce((match, [all, id, title]) => ({ ...match, [id]: title }), {});
}).catch(err => {
    console.warn('Something went wrong.', err);

will give you e.g.

    Header: "Header"
    , LeftColumn: "Left Column"
    , RightColumn: "Right Column"
    , Footer: "Footer"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.