Home / Blog / JavaScript & TypeScript

API & webhooks

GET API Requests in JavaScript: Build a Search URL from a Form

Build GET queries from a browser form, preserve reserved characters and repeated values, and verify the request independently from rendering results.

Keep a search form's values separate from URL syntax

A JavaScript search form should construct a URL from the user's values instead of concatenating raw text into a query string. An ampersand, plus sign or percent sign can otherwise change how the server interprets the request while the resulting URL still appears plausible.

For a fictional notes search, the form supplies one q value and zero or more tag values. The service interprets repeated tag parameters as a list. That convention belongs to this example's endpoint contract; another API may use a different representation.

Build the query with FormData and URLSearchParams

function searchUrlFromForm(form, endpoint) {
  const data = new FormData(form);
  const query = data.get("q");
  if (typeof query !== "string") throw new Error("A text query field is required.");
  const tags = data.getAll("tag");
  if (tags.some(tag => typeof tag !== "string")) {
    throw new Error("Tags must be text values.");
  }
  const url = new URL(endpoint);
  url.searchParams.set("q", query);
  url.searchParams.delete("tag");
  for (const tag of tags) url.searchParams.append("tag", tag);
  return url;
}

The endpoint is trusted application configuration, not another uncontrolled form field. The helper replaces any existing q and tag values while retaining unrelated endpoint parameters. It preserves the query text as entered, including spaces, because this example does not define trimming as part of its search semantics.

Form controls need the intended name attributes to participate. For example, an input named q supplies the query, and checked controls named tag can supply repeated tags. A field's visible label or id alone does not create its FormData entry.

Disabled controls and unchecked checkboxes also affect which values are submitted. Test the form's actual enabled and checked state rather than reconstructing it from visible text. If a disabled field must influence the query, define that behavior explicitly outside the default FormData collection.

Integrate with the form's normal submit behavior

Listen to the form's submit event so keyboard submission and the submit button follow the same path. In that handler, prevent the ordinary navigation only when the JavaScript application is taking responsibility for the request and result display.

Call the helper, then send fetch(url, {method: "GET"}) under the endpoint's intended credential policy. Do not append a JSON request body to carry the same search fields. The GET method reference describes the read operation and its request semantics.

A form can also have a useful native GET fallback when its action and fields match the service or application route. Decide whether that fallback is intended before changing the page's submit behavior. A script error should not silently send the user to an unrelated endpoint.

Check the values received by the server

For q equal to river & rail + π, the parsed server-side value should contain the same characters. For tags map and walking, getAll("tag") should return both in the submitted order. Test a query that already contains a literal percent sign so accidental double encoding becomes visible.

The URLSearchParams reference describes its encoding and repeated-value operations. Inspect parsed values rather than asserting a single preferred spelling of every encoded character in the raw URL.

Keep rendering and request ownership outside the URL helper

This function constructs the request URL only. It does not check HTTP status, parse the response, render result items or cancel an older request. Those responsibilities belong in the caller and need their own tests.

When two searches overlap, commit only the current search's result. A slow response for river must not replace a newer mountain search. Clear or label earlier output while loading, and render returned titles through safe text bindings rather than interpreting them as HTML.

Exercise missing controls and changed submissions

Test two distinct queries, multiple tags, no tags and an empty query. A missing q control or a file-valued tag should fail under this helper's contract. Confirm that unrelated configured query parameters survive and that stale configured tag values are replaced.

The REST API Testing Tool can inspect the resulting GET against an authorized service. It does not read your page's form or prove that keyboard submission works. Verify the form event and URL construction in the application that owns those controls.