Website button not working? Test every CTA and form before launch
A button that does nothing is usually a clickable div, a form with no submit path, a thrown handler or a banner on top. The test that finds each.
LLaunchScaler·Published ·8 min read
A "Get started" button that does nothing is almost always one of five faults: it is a <div> with a click handler that never attached or only answers the mouse, its form has no working submit path, its handler throws before it navigates, a script it depends on failed to load, or a cookie banner or sticky bar is sitting on top of it. You find all five by testing every primary control with the mouse, with the keyboard, at 320 pixels wide and with the consent banner still showing.
This guide gives the cause table, the form checks and a test script to run on every primary control before launch day. Run it on the homepage, pricing and signup pages at least, because those are the pages a launch sends people to.
Why does a button do nothing when you click it?
A click does nothing when no code responds to it, when code responds and fails, or when the click never reaches the button. The console and the keyboard tell you which. If the console shows an error on click, the handler failed. If Tab cannot reach the control, it is not a real button. If a click lands on something else, an overlay is in the way.
What you see
Likely cause
How to confirm
Fix
Nothing happens on click, console is clean
A <div> or <span> whose handler never attached, often after a hydration failure
Right-click, Inspect: is it a <button> or <a href>? In Elements, check its Event Listeners tab
Questions, answered
What people ask about this
01
Why is the button on my website not working?
Usually the button is a div with a mouse-only click handler, its handler throws before it navigates, a script it depends on failed to load, or a cookie banner or sticky bar sits on top of it. Open the console, click it, then press Tab to reach it and Enter to activate it.
Make it a <button> or an <a href>, and check the page hydrates cleanly
Nothing happens, an error appears on click
The handler throws on its first line, often calling a third-party script that was blocked
Read the error in the console
Guard the call and let the primary action run first
Works with the mouse, not the keyboard
A clickable <div> with no tabindex and no key handling
Press Tab: focus skips it, or Enter and Space do nothing
Use a native <button>
Page reloads and the form clears
A form with no action and no handler, or a <button> whose default submit reloads the page
Watch the Network panel for a request to the page's own URL
Add a real endpoint or a submit handler that calls preventDefault() and sends the data
Spinner, then the button resets
The form endpoint returned an error and the UI shows nothing
Network panel: status of the POST
Fix the endpoint and show an explicit error message
The click lands on something else
A cookie banner, chat bubble or sticky bar covers the control
Elements panel: hover the spot and see which element highlights
Move or shrink the overlay, or make it non-modal
The button is missing on a phone
The layout pushes it off-screen or under another element at narrow widths
Device toolbar at 320 px
Fix the breakpoint
The first row is the one that fools people, because the button looks finished. When the page's JavaScript fails early, including the hydration failure described in the Next.js hydration error guide, a styled <div> stays on screen with no handler behind it.
Why must a CTA be a real button or link?
Because only native controls work for every kind of visitor without extra code. WCAG success criterion 2.1.1 (Level A) requires that all functionality be operable through a keyboard interface. A <button> or <a href> is focusable and activates from the keyboard by default; a <div> with an onclick is neither.
MDN's page on the ARIA button role spells out what a <div> needs to catch up: a tabindex to make it focusable, and separate key handlers for Enter and Space, because a non-button element's onclick only fires for the mouse even with role="button". It then recommends native buttons instead, since they "provide keyboard and focus requirements by default."
The same markup decides whether software can use your page. OpenAI has said its ChatGPT Atlas browser uses ARIA tags, the same labels and roles that screen readers rely on, to interpret page structure and interactive elements, as quoted in Adrian Roselli's analysis of that guidance. Roselli's advice is the right one to follow: use semantic HTML first and treat ARIA as a fallback. A real <button> already carries the role an agent looks for. The guide to making a website usable by AI agents covers the rest of what agents need.
The rule for choosing between the two elements:
The control takes the visitor to another page, such as /signup or /pricing: use <a href="/signup">. It works before JavaScript loads and when it fails.
The control does something on this page, such as submitting a form, opening a dialog or starting checkout: use <button>.
Never put one inside the other. An <a> inside a <button> is invalid nesting, and in a React app it also causes a hydration error.
Why is my form not submitting?
A form submits only when it has somewhere to send the data and a control whose type actually submits. MDN states that a form with no action sends its data to the URL of the page containing it, so a form with neither an action nor a handler reloads the current page and discards what the visitor typed.
Check these in order:
The form has an action pointing at a real endpoint, or a submit handler that calls event.preventDefault() and then sends the data with fetch. A handler that prevents the default and sends nothing is a dead form.
The submit control is <button type="submit"> or a <button> with no type inside the form. MDN notes that submit is the default for a button associated with a form, and that type="button" "does nothing when pressed by default." A signup button marked type="button" with no handler looks right and submits nothing.
Other buttons in the form, such as "Show password" or "Apply coupon", are type="button", otherwise they submit the form too. MDN warns that a button left as submit will try to submit the form data and can destroy the current state of the page.
The endpoint returns a success status for valid input, and the page shows a confirmation. If it fails, the page shows an error message rather than resetting the button silently.
Valid input is accepted. An email regex that rejects name+tag@example.com turns away real signups.
Validation is where many working forms still lose people. Baymard's January 2024 research found that 31% of the sites it benchmarks have no inline validation at all. Its recommendation is to validate when the visitor leaves a field (the blur event), not while they are still typing, and to remove the error message the moment the input becomes valid.
Can a cookie banner block your CTA?
Yes, and it is easy to miss because you dismissed your own banner weeks ago. A consent overlay that spans the viewport, or a bottom bar that covers the lower third of a phone screen, can sit on top of the primary button and intercept the click. A first-time visitor sees the page with the banner showing, so that is the state to test.
Test it in a fresh browser profile, where no consent has been stored. Load each landing page, and before touching the banner, try to click the primary CTA. If the banner blocks it, the visitor has to deal with the banner first. The fix is a banner that does not overlay primary controls, or one whose Reject option is as easy to reach as Accept. The rules regulators apply to that choice are in the guide to cookie banner requirements.
Chat bubbles and sticky promotional bars cause the same fault. On a phone, a fixed chat launcher in the bottom-right corner can sit exactly where a full-width signup button ends up.
How do you test every CTA and form before launch?
Run one short script for each primary control: the header CTA, the hero CTA, the pricing plan buttons, the signup form and any "Book a demo" control. For every control, each pass must produce a visible effect, which means a navigation, a network request or a change on the page. A pass with no effect is a failure.
Open a fresh Chrome profile or Guest window so no consent, cache or session is stored. Open DevTools on the Console tab.
With the cookie banner still showing, click the control with the mouse. Note what happened and any console error.
Accept or reject the banner, reload, and click again.
Press Tab from the top of the page until focus reaches the control. Confirm you can see where focus is. Press Enter. For a <button>, reload and try Space as well.
Open the device toolbar, choose the Mobile S preset (320 px) and repeat steps 2 and 4. WCAG's Reflow criterion uses a width equivalent to 320 CSS pixels, which is also what a 1280-pixel window shows at 400% zoom.
For each form: submit it empty, submit it with one invalid field, then submit valid test data. Check each response in the Network panel and confirm the page tells the visitor what happened.
Double-click the submit button and confirm it sends one request, not two.
Repeat on one real phone. Chrome describes device mode as "a first-order approximation," not a real device.
Keep the results as a table with one row per control and one column per pass, and fix every empty cell before launch. Then work through the console on the same path, because a clean button can still sit on a page with errors that break the step after it; the guide to console errors on your landing page sorts those. The wider pre-launch checks, from caching to rate limits, are in the guide to getting a website ready for launch traffic.
Have your live CTAs tested on every scan
Your own test catches what your browser sees on the day you run it. To have the live pages checked by a real browser each time you scan, run the free scan first, then open the full audit. The free LaunchScaler scan needs only your URL and no account, and runs 156 checks across 6 of its 7 categories. Its does-it-work checks include "Primary CTA is a dead control with no navigation or handler", "Primary controls not operable by keyboard", "Form cannot submit: no action, no handler, no endpoint", "Cookie/consent banner overlay blocks interaction with the page" and "Valid input rejected, and no inline validation before submit".
The free run shows each check's verdict. The full audit, $19 one time for your domain, opens every check to its evidence and its exact fix, so you see which control failed, what the browser observed when it was clicked and what to change.
Check that the form has either an action URL or a submit handler that sends the data, and that the button is type submit. A button with type button does nothing by default, and a form with no action sends its data to the page it is on.
03
Should a call to action be a link or a button?
Use an a element with an href when the control takes the visitor to another page, and a button element when it performs an action such as submitting a form or opening a dialog. Both are focusable and keyboard-activatable without extra code.
04
What screen width should I test a landing page at?
Test at 320 CSS pixels, the width WCAG's Reflow criterion uses, as well as at your common phone widths. Chrome DevTools' device toolbar has a Mobile S preset at 320 px.
05
When should a form validate its fields?
When the visitor leaves each field, not while they are still typing, and the error should disappear as soon as the input becomes valid. Baymard's research found that 31% of the sites it benchmarks have no inline validation at all.
Two curl commands show whether your .env or .git folder is public. What a leak looks like, why deleting the file is not enough, and the rotation steps.