SharePoint 2013 introduces the new app model making it possible to integrate externally hosted apps into SharePoint. One of the features of the new app framework is the so called “Chrome Control” which enables the externally hosted apps to dynamically load the SharePoint CSS and thus implement the same look and feel as SharePoint. There is a nice example on how to use the Chrome Control at http://msdn.microsoft.com/en-us/library/fp179916.aspx, so I will not go into the basics here. Rather, I want to point you to a nasty bug in the current SharePoint 2013 version which might affect you if you are loading the Chrome Control declaratively.
Note: you only need the Chrome Control in your provider or autohosted apps that run outside of the SharePoint context. You don’t need the Chrome Control in the SharePoint hosted apps since those run in the SharePoint context and can reference the necessary styles by referencing the SharePoint master page.
So pretty much just copy-paste from the MSDN article above. The important part is the SPWorkshop.ChromeControl.render() method. Here we first define the options for the Chrome Control (lines 11-29) and then load it in the line 31. In the options I specified several other pages that should be linked up in the Chrome Control (Contacts.aspx, Welcome.aspx, Help.aspx) and I want to pass the original URL query string to all those pages so that they can access all the SharePoint context info passed in the URL. I did it like this:
"linkUrl": "../Pages/Contacts.aspx?" + document.URL.split("?")
And this works fine, when I load the page, my Chrome Control is loaded and when I click on the “Settings” wheel in the top right corner I can see the link to the Contacts.aspx page in the status bar containing the query string with the SharePoint context info:
When I click on the Contacts link, I am redirected to the Contacts.aspx page and the entire query string is copied over, so my URL looks something like
See that pulp after Contacts.aspx? That’s the context info that SharePoint passed to my Default.aspx and that I now passed on to the Contacts.aspx thanks to that “…document.URL.split("?")” line in the Chrome Control options. So far, so good.
Now on to the problem. The alternative way to load the Chrome Control in your page is declaratively through your aspx markup, something like this:
To prove that this is correct, remove the “+ document.URL.split("?")” from the markup and redeploy your app again, this time the Chrome should load fine, except that your links to the Contacts.aspx and other pages now no longer get all the nice info from the URL query string (again, pay attention to the URL in the status bar, now without the query string):
Note: examples similar to this one with attempts to pass the query string to the pages in a declarative Chrome Control were used in highly popular and otherwise highly recommended books “Inside Microsoft SharePoint 2013” and “Microsoft SharePoint 2013 App Development” and they won’t work either due to the same problem – so don’t waste your time looking for the solution, there is none at this moment (SP 2013 with April 2013 CU).