I am trying to create a chrome extension which summarizes the selected text from a webpage by using Gemini API. But whenever i try to run the extension an error occurs :
Error: Cannot access contents of the page. Extension manifest must request permission to access the respective host.
I don’t think there’s any issues with the backend.
I have tried all possible fixes but couldn’t resolve it.
Another issue is that sidepanel is missing from my chrome and not showing up by any mean. Therefore i tried building it as a popup window.
Here’s my frontend code:
manifest.json
{
"manifest_version":3,
"name":"Research Assistant",
"version":"1.0",
"description":"AI Powered Research Assistant",
"permissions":[
"activeTab",
"storage",
"scripting"
],
"action":{
"default_title":"Reasearch Assistant"
},
"side_panel":{
"default_path":"sidepanel.html"
},
"background":{
"service_worker":"background.js"
},
"host_permissions":[
"http://localhost:8080/*",
"<all_urls>",
"http://*/",
"https://*/"
],
"content_security_policy":{
"extension_pages":"script-src 'self'; object-src 'self'"
}
}
sidepanel.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Research Assistant</title>
<link rel="stylesheet" href="sidepanel.css">
</head>
<body>
<div class="container">
<div class="header">
<h2>Research Assistant</h2>
</div>
<div class="actions">
<button id="summarizeBtn">Summarize</button>
</div>
<div id="results"></div>
</div>
<script src="sidepanel.js"></script>
</body>
</html>
sidepanel.js
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('summarizeBtn').addEventListener('click', summarizeText);
});
async function summarizeText() {
try {
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
const [{ result }] = await chrome.scripting.executeScript({
target: { tabId: tab.id },
function: () => window.getSelection().toString()
});
if (!result) {
showResult("Please Select Some Text First!");
return;
}
const response = await fetch('http://localhost:8080/api/research/process', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content: result, operation: 'summarize' })
});
if (!response.ok) {
throw new Error(`API Error: ${response.status}`);
}
const text = await response.text();
showResult(text.replace(/n/g, '<br>'));
} catch (error) {
showResult('Error: ' + error.message);
}
}
function showResult(content) {
document.getElementById('results').innerHTML = `<div class="result-item"><div class="result-content">${content}</div></div>`;
}
background.js
chrome.action.onClicked.addListener(async () => {
try {
await chrome.windows.create({
url: "sidepanel.html",
type: "popup",
width: 400,
height: 600
});
} catch (error) {
console.error('Failed to create window:', error);
}
});
async function getCurrentTab() {
try {
const queryOptions = { active: true, lastFocusedWindow: true };
const [tab] = await chrome.tabs.query(queryOptions);
return tab;
} catch (error) {
console.error('Failed to get current tab:', error);
return null;
}
}