How to open Google search results in the sidebar

Hello,

I created an extension that amongst other things opens Google search results in the sidebar. However, the search results are truncated and do not fit (i.e. the lines don’t wrap) within the width of the sidebar.

I tried to correct this by specifying a mobile user agent in the web request, but it doesn’t do anything:

/// Add a mobile header to outgoing requests
browser.webRequest.onBeforeSendHeaders.addListener(
    rewriteUserAgentHeader,
    requestFilter,
    ["blocking", "requestHeaders"]
);

/*
Rewrite the User-Agent header to contextsearch_userAgent
*/
function rewriteUserAgentHeader(e) {
    if (!contextsearch_openSearchResultsInSidebar) {
        return {};
    }
    for (const header of e.requestHeaders) {
        if (header.name.toLowerCase() === "user-agent") {
            header.value = contextsearch_userAgent;
        }
    }
    return { requestHeaders: e.requestHeaders };
}

I also tried setting the viewport width using a solution proposed by chatGPT, but that generated an error as it seems that width was not recognised:

// Get the current active tab
browser. tabs. query({active: true,
currentWindow: true}).then(tabs => {
const activeTab = tabs[0];
// Open the Google search results in a
sidebar with modified viewport size
browser.sidebarAction.open({
url: "https://www.google.com/search?
q=${activeTab.title}',
tabId: activeTab.id
});
/ Modify the viewport size of the sidebar
browser.sidebarAction.setPanel({
width: 360,
height: 640
});
});

I would be most grateful if anyone could help fix this problem.
Thank you.

Using the mobile user agent should work.
I’ve just tested it in one of my projects using following (very old) typescript code and it works:

  browser.webRequest.onBeforeSendHeaders.addListener(function (details: browser.webRequest._OnBeforeSendHeadersDetails) {
    console.log('header', details);
    const headers = details.requestHeaders!;
    for (let i = headers.length - 1; i >= 0; --i) {
      const header = headers[i];
      const headerName = header.name.toLowerCase();
      if (headerName === 'user-agent') {
        header.value = 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/12.0 Mobile/15A372 Safari/604.1';
        // header.value = 'Mozilla/5.0 (Linux; Android 7.0; SM-G892A Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/67.0.3396.87 Mobile Safari/537.36';
      }
    }
    return {requestHeaders: headers};
  }, {
    urls: ['<all_urls>'],
    tabId: targetTabId || undefined,       // block only target tab (or pop-up)
    types: ['sub_frame'],     // block only "iframe" requests
  }, ['blocking', 'requestHeaders']);

PS:
do I see that you are using “Search Result Previews” addon? That’s my addon! :smiley:

Hi Juraj,

Thank you for your quick response.

I tried changing the user agent to the one in your code. I also tried changing the type from main_frame to sub_frame, but I just can’t get it to work! What does targetTabId point to? Are you sure that you’re using the Firefox in-built sidebar? (I don’t see the “x” to close the sidebar!)

I just don’t know what is causing the problem.

P.S. Yes, you’re absolutely right, I’m using your awesome add-on! Thank you.

Could the problem lie elsewhere and maybe have to do with the html and css that I’m using for the sidebar?

search_results.html :

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=430, initial-scale=1.0">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Raleway&display=swap">
    <link rel="stylesheet" href="../styles/search_results.css" />
</head>

<body>
    <div id="searchResultsContainer">

    </div>
</body>

</html>

search_results.css :

html,
body {
    scroll-behavior: smooth;
    overflow-y: scroll;
    height: 100%;
    width: 100%;
    max-width: 432px;
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Raleway', Calibri, Helvetica, Arial, sans-serif;
    font-size: 10pt;
    color: darkslategrey;
}

I tried using another extension call Open in Sidebar. I did a Google search for “Taïwan” in a tab, then I did a right-click on “All” and selected “Open Page in Sidebar”. Again, the search results were truncated, so this isn’t just happening with my extension. Btw, I’m using Firefox Developer Edition 111.0b8 (64-bit).

Other extensions are having the same problem:

Oh, that’s a sidebar, right… that may complicate things a bit.
My example was build for page displayed in “iframe”. But don’t put your page inside iframe!

But there is almost no difference, the “sub_frame” I’m using means it will affect only iframes, so you don’t want to use that, keep it to “main_frame”.

Also, what requestFilter are you using?
Are you sure the right requests are handled? Put some console logs in the handler just to be sure it’s running.
And lastly, when do you register it? You need to register it before the page starts loading.

But I’m a bit puzzled about that requestFilter… in my case I target a targetTabId , which is ID of the tab where the iframe is, but how to target a sidebar? :slight_smile:

From what I understand, you target the sidebar by setting the tabID to -1. Here’s my request filter:

// This is a RequestFilter: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest/RequestFilter
// It matches tabs that aren't attached to a normal location (like a sidebar)
// It only matches embedded iframes
const requestFilter = {
    tabId: -1,
    types: ["main_frame"],
    urls: ["http://*/*", "https://*/*"]
};

Not sure what you mean by registering? My web request handler is in the background script.

Are you sure you target it by setting tabId to negative one? Where did you see that?

But more importantly, did you put a console.log into the “rewriteUserAgentHeader” handler? Do it to see if it’s actually being executed.

I update the sidebar panel with:

browser.sidebarAction.setPanel({ panel: targetUrl });

I added some console.logs as shown here, but they’re producing no output so the web request listener isn’t catching anything!

/*
Rewrite the User-Agent header to contextsearch_userAgent
*/
function rewriteUserAgentHeader(e) {
    if (!contextsearch_openSearchResultsInSidebar) {
        return {};
    }
    console.log(`Intercepted header: ${e.requestHeaders}`);
    for (const header of e.requestHeaders) {
        if (header.name.toLowerCase() === "user-agent") {
            header.value = contextsearch_userAgent;
        }
    }
    console.log(`Modified header: ${e.requestHeaders}`);
    return { requestHeaders: e.requestHeaders };
}

From what I can see in the docs, the sidebar seems to belong to the window, so maybe you need to use windowId instead.

I’ve tried to execute these two inside a sidebar and these are the results:
image

The sidebar can be linked to tab, window or global pane. I thought I was using global pane.

Try to omit both “tabId” and “windowId” in the request filter, that should make it global.
It’s not ideal but let’s try just to be sure it works.

I tried it but it doesn’t produce any output, so maybe you’re right and I need to link to the windowID.

According to ChatGPT:

No, the browser.sidebarAction.setPanel({ panel: targetUrl }) method call does not trigger a web request.

This method is used to set the content of the sidebar panel to a specified URL, which can be a local file or a remote resource. The browser then fetches the content of the specified URL and displays it in the sidebar panel.

However, if the URL specified in panel points to a remote resource, then a web request will be made to fetch the content of that resource. This request is initiated by the browser itself and not by the browser.sidebarAction.setPanel method.

It’s also worth noting that the browser.sidebarAction.setPanel method is asynchronous, which means that it does not block the execution of other code while the browser fetches the content of the specified URL. Instead, it returns a Promise that resolves when the panel is set.

Would a genius from Mozilla please help!