Documentation pages have a frustrating gap: the user reads something confusing, switches to ChatGPT, and then has to re-type or paste the exact context they were looking at. A small JavaScript button can close that gap entirely. When clicked, it opens ChatGPT in a new tab with a prompt already built from the current page — the title, the section heading, and optionally whatever text the user has selected.
This technique works on any static site (Astro, Eleventy, plain HTML) without a backend, without an API key, and without any third-party service. It relies on an undocumented but reliable ?q= URL parameter that chatgpt.com reads on page load and auto-submits as the opening message. The same pattern works with Claude (claude.ai/new?q=) and Perplexity (perplexity.ai/search?q=) if you want to add variants.
How the URL parameter works
When you open https://chatgpt.com/?q=Hello%20world, ChatGPT's web app reads the q parameter, inserts the decoded value into the input field, and submits it automatically. This was discovered by security researchers and is now widely used by prompt-sharing tools. OpenAI has not removed it — as of mid-2026 it remains functional, though it is not officially documented and carries no stability guarantee.
The implication for documentation sites: you can programmatically construct a meaningful prompt string, URL-encode it, and pass it in. ChatGPT opens straight into a conversation with your context already loaded.
Step 1 — Add the button to your HTML
Place the button wherever makes sense on your docs page. A sensible location is the top of the article body, or inline with the page heading. Keep it visually lightweight — this is a helper, not a primary action.
<button id="ask-chatgpt" type="button">
Ask ChatGPT about this page
</button>
If you have multiple docs pages, put this in your shared layout so it appears everywhere automatically.
Step 2 — Write the JavaScript
The script does three things: it reads context from the current page, builds a prompt string, and opens the ChatGPT URL. Put this in a <script> tag at the bottom of your layout, or in a separate .js file you load with defer.
document.addEventListener("DOMContentLoaded", function () {
var btn = document.getElementById("ask-chatgpt");
if (!btn) return;
btn.addEventListener("click", function () {
var pageTitle = document.title || "this page";
// Look for the nearest section heading — fall back to the page title.
var heading = document.querySelector("h1, h2");
var sectionTitle = heading ? heading.textContent.trim() : pageTitle;
// Use highlighted text if the user has selected something.
var selectedText = "";
var selection = window.getSelection();
if (selection && selection.toString().trim().length > 0) {
selectedText = selection.toString().trim();
}
// Build the prompt.
var prompt;
if (selectedText) {
prompt =
"I am reading the documentation page \"" +
sectionTitle +
"\" and I have a question about this passage:\n\n" +
"\"" +
selectedText +
"\"\n\n" +
"Can you explain it clearly?";
} else {
prompt =
"I am reading the documentation page \"" +
sectionTitle +
"\" on the site \"" +
pageTitle +
"\". Can you explain what this covers and answer any questions I have about it?";
}
var url =
"https://chatgpt.com/?q=" + encodeURIComponent(prompt);
window.open(url, "_blank", "noopener,noreferrer");
});
});
What each part does
- Page title:
document.titlegives the full browser tab title, which usually contains the site name and the article name — useful context for ChatGPT. - Section heading:
document.querySelector("h1, h2")picks the first prominent heading on the page. If your docs use a deeper structure, adjust the selector (e.g.article h2) to target the nearest relevant heading. - Selected text:
window.getSelection().toString()returns whatever text the user has highlighted. When present, the prompt quotes that passage directly — this is the most useful path because the user has already told you what confused them. encodeURIComponent: mandatory. Without encoding, spaces, quotes, newlines, and ampersands will break the URL silently or produce a garbled prompt.noopener,noreferrer: standard practice when opening third-party tabs. Prevents the new tab from accessingwindow.openerand strips the referring URL.
Step 3 — Make the button context-aware
The base version above covers most cases, but you can make the prompt richer with a little more DOM reading. If your docs have a breadcrumb or a data-section attribute on the body, include that too:
// Pull a breadcrumb string if your docs render one.
var breadcrumb = document.querySelector(".breadcrumb, nav[aria-label='breadcrumb']");
var breadcrumbText = breadcrumb ? breadcrumb.textContent.replace(/\s+/g, " ").trim() : "";
// Pull the URL so ChatGPT can reference the exact page.
var pageUrl = window.location.href;
var prompt =
"I am reading the documentation page \"" +
sectionTitle +
"\" (" +
pageUrl +
")." +
(breadcrumbText ? " Section path: " + breadcrumbText + "." : "") +
" Can you explain what this covers and answer my follow-up questions?";
// If the user selected text, prepend that instead.
if (selectedText) {
prompt =
"I highlighted this passage on the page \"" +
sectionTitle +
"\":\n\n" +
"\"" +
selectedText +
"\"\n\n" +
"Can you explain it in plain terms?";
}
Including the URL in the prompt is useful because ChatGPT can acknowledge which page you mean, and users can paste the conversation link alongside their bug report or question.
Step 4 — Handle the Astro case
If you are using Astro, drop the script into your docs layout with the is:inline directive so Astro does not process it as a module:
<!-- src/layouts/DocsLayout.astro -->
<button id="ask-chatgpt" type="button">
Ask ChatGPT about this page
</button>
<script is:inline>
document.addEventListener("DOMContentLoaded", function () {
var btn = document.getElementById("ask-chatgpt");
if (!btn) return;
btn.addEventListener("click", function () {
var sectionTitle =
(document.querySelector("h1") || {}).textContent ||
document.title;
var selectedText = (window.getSelection() || {}).toString().trim();
var prompt = selectedText
? "On the page \"" + sectionTitle.trim() + "\", I selected:\n\n\"" + selectedText + "\"\n\nCan you explain this?"
: "I am reading the docs page \"" + sectionTitle.trim() + "\". Can you explain what this covers?";
window.open(
"https://chatgpt.com/?q=" + encodeURIComponent(prompt),
"_blank",
"noopener,noreferrer"
);
});
});
</script>
If you are using Astro's view transitions, wrap the listener in document.addEventListener("astro:page-load", ...) instead of DOMContentLoaded, so the button re-attaches after client-side navigation.
What to expect from the user experience
A user reading your docs highlights a confusing sentence and clicks the button. ChatGPT opens in a new tab with that sentence already quoted in a prompt asking for a plain-English explanation. The conversation starts immediately. There is no copy-pasting, no blank chat box to stare at, and no "give me context" back-and-forth.
Without a selection, the prompt is more open-ended: it names the page and asks ChatGPT to be ready to answer follow-up questions. This works well for users who are browsing rather than stuck on a specific sentence.
Known limits
- The
?q=parameter is not officially documented by OpenAI. It works as of mid-2026 but could be removed or restricted. Build the button as a convenience, not a load-bearing feature. - ChatGPT requires the user to be signed in. If they are not, they will see the login screen first — the prompt is still in the URL and will be submitted after they sign in, but the flow is interrupted.
- Very long selections (thousands of words) may be truncated or hit URL length limits in some browsers. A practical cap is around 2,000 characters of prompt text. If you want to handle longer content, truncate the selected text before encoding it.
- This technique does not give ChatGPT live access to your docs. It only passes what you put in the prompt string. ChatGPT cannot follow links or read the page in real time from this approach alone.
Extending it
A few natural next steps once the basics are working:
- Add a character limit check. If
selectedText.length > 1500, slice it and append"[...]"so the URL stays manageable. - Support multiple AI tools. Render a small dropdown or a set of icon buttons: one for ChatGPT (
chatgpt.com/?q=), one for Claude (claude.ai/new?q=), one for Perplexity (perplexity.ai/search?q=). Each uses the same encoded prompt string. - Inject your product name. Prefix the prompt with
"In the context of [Your Product], ..."so ChatGPT's answer stays on-topic rather than giving generic advice. - Track usage. A lightweight analytics event on button click (no personal data, just a page-path event) will tell you which docs pages generate the most ChatGPT handoffs — those are your clearest candidates for rewriting.
The whole implementation is about 25 lines of vanilla JavaScript with no dependencies. It makes your documentation meaningfully more useful for the large share of readers who already have ChatGPT open in another tab — and it saves them the friction of switching contexts just to ask a question.