Add prefix to each line
Put the same marker at the start of every line: with two slashes and a space as the prefix, first line, second line and third line become 3 commented lines. A hash comments shell scripts, a greater-than sign quotes an email. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- first line second line third line
- Prefix
- //
- Input
- first line second line third line
- Line count
- 3
- Lines
- // first line, // second line, // third line
- Prefixed
- // first line // second line // third line
An add-prefix-to-each-line tool turns a raw paste of code, email body, notes, or checklist into a uniformly marked block you can drop into tickets, reviews, and documentation. Enter any non-empty multi-line or single-line string plus the prefix you want at the start of every line—common choices include double-slash and space for JavaScript comments, hash and space for shell or Python comments, greater-than and space for email-style quotes, or two spaces and a dash for indented lists. The tool normalizes Windows and classic Mac newlines, splits on each line break, and prepends your prefix to every segment, including empty interior lines, so the shape of the document stays stable.
How prefixing every line works
Prefixing lines is one of the oldest bulk-editing patterns in programming and technical writing: every visual line gets the same leading marker so people can comment out a whole block, quote a message, or mark a list without clicking line by line in an editor. This capability implements that everyday rule on plain text rather than on rich-text documents or IDE multi-cursors. First the input is checked: missing text, a non-string value, or a string that is empty after trimming whitespace is rejected so blank pastes never look like success.
Newlines are normalized so Windows CRLF, old Mac CR, and Unix LF all become a single LF form before splitting. The splitter then breaks the string on every LF; each resulting segment—including empty segments between consecutive newlines—is one line and receives the same prefix at its start. Interior content of each line is left unchanged: only the beginning of the line is modified.
When you need sequential numbers instead of a fixed marker, use a line-numbering capability; when you need to strip spaces from line edges, use a per-line trim tool. This landing is only about prepending one chosen string onto every plain-text line.
Practical tips, limits, and when to use this tool
Use this capability when the search intent is add prefix to each line, prepend text to lines, comment a code block, or quote every line of an email. Paste a code snippet and set prefix to double-slash and space to comment it out for a review note; use hash and space for shell scripts; use greater-than and space to turn a pasted reply into a blockquote; use two spaces and a dash to turn plain lines into a nested list marker.
Keep intentional trailing newlines in mind: a final LF creates an empty last segment that still receives the prefix, which matches how many editors treat end-of-file newlines. Extremely long single lines still count as one line each; the tool does not wrap by character width. HTML and Markdown source are prefixed as raw strings; strip markup first if you only want visible prose lines.
This landing is not a sequential line numberer, not a per-line trimmer, not a find-and-replace engine, and not a full IDE multi-cursor. Prefer line numbering when reviewers must cite exact indices; prefer per-line trim when the problem is uneven leading spaces; prefer this capability when every line needs the same fixed marker. When teaching code style, prefix the same snippet twice with different markers so learners see how comment syntax differs across languages while the transform stays stable.
What you can do with it
Comment out code blocks
Paste a snippet, set prefix to "// " or "# ", and get a fully commented block ready for tickets, reviews, or temporary disable notes.
Quote email and chat replies
Prefix every line with "> " to turn a pasted message into a classic email-style quote for replies and documentation.
Build marked or indented lists
Add " - ", "* ", or a custom marker to plain lines so checklists and notes share a consistent list style.
FAQ
How are lines defined?
After normalizing CRLF and CR to LF, the text is split on every LF. Each segment—including empty ones between consecutive newlines—receives the same prefix at the start.
What happens on empty input?
A missing or non-string prefix also fails validation.
Can the prefix be empty?
Yes. An empty prefix string is allowed and acts as a no-op after newline normalization. Non-string or oversize prefixes (over 256 characters) are rejected.
Does this add sequential line numbers?
No. It prepends the same fixed string to every line. Use a line-numbering tool when you need 1., 2., 3. style labels.
Is the add-prefix tool free?
The browser tool is free and runs locally.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/str/prefix-lines \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"first line\nsecond line\nthird line","prefix":"// "}'const res = await fetch("https://api.kit.forhosting.com/str/prefix-lines", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "first line\nsecond line\nthird line",
"prefix": "// "
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/str/prefix-lines",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "first line\nsecond line\nthird line",
"prefix": "// "
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/str/prefix-lines", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"first line\\nsecond line\\nthird line","prefix":"// "}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"first line\nsecond line\nthird line","prefix":"// "}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/str/prefix-lines", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "first line\nsecond line\nthird line",
"prefix": "// "
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "str.prefix_lines",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_chars | 100000 |
max_prefix_chars | 256 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
Empty or whitespace-only text is rejected with a clear invalid_input error so automation never treats a blank form as a successful transform.
How prefixing every line works
The prefix field is required as a string and may be empty if you only want newline normalization; non-string or oversize prefixes fail with invalid_input.
How to call the API and what the response contains
The prefix string may be empty and must not exceed two hundred fifty-six characters, which covers multi-character comment openers, markdown quote markers, and short indentation patterns without allowing multi-kilobyte abuse. Prefer sending the raw document body with its real line breaks rather than pre-joining everything into one line when you want true multi-line prefixes. Send a JSON body with two required string fields: text (aliases input, value, string, s, content, and body) and prefix (aliases pre, head, marker, and bullet). The text value must be non-empty after whitespace is trimmed and must not exceed one hundred thousand characters so a single request cannot exhaust Worker or browser memory on huge paste dumps. On success the response echoes input as the original string you sent, text as the trimmed working string, prefix as the effective marker, line_count as the number of prefixed segments, lines as an ordered array of fully prefixed line strings, prefixed as those lines joined with LF, and message as a short English summary that reports how many lines were prefixed and with which marker. Failed validation—missing text, a non-string value, an oversize payload, empty content after trim, a missing or non-string prefix, or an oversize prefix—returns invalid_input and is never charged. Pricing is a flat $0.002 per successful request with unit item. When integrating, assert on prefixed or lines for the full listing, on line_count for the total, and treat invalid_input as a client bug for blank form submissions rather than a billing event.
Practical tips, limits, and when to use this tool
Round-trip checks for tests are easy: feed three short lines separated by LF with prefix "// " and expect line_count three and every lines entry starting with that marker; deliberately send empty string or spaces for text to confirm invalid_input and the message that asks for a non-empty string. Failed tasks that return invalid_input do not consume prepaid balance, which keeps form validation and CI negative tests cheap.