Text Repeater
Repeat any text as many times as you like, with a separator, optional numbering and line breaks between copies — useful for test data and templates.
Ten copies take nine separators
Joining n pieces puts a separator between them, so there are n − 1. Obvious stated plainly, and the reason the "separator after the last copy" checkbox exists: pasting a repeated block into a list, or building a row of comma-separated values, usually wants the trailing one, and joining alone will never give it to you.
| Copies | Separators | Result | With the trailing one |
|---|---|---|---|
| 1 | 0 | Hi | Hi, |
| 2 | 1 | Hi, Hi | Hi, Hi, |
| 5 | 4 | Hi, Hi, Hi, Hi, Hi | Hi, Hi, Hi, Hi, Hi, |
| 10 | 9 | Hi, Hi, Hi, Hi, Hi, Hi, Hi, Hi, Hi, Hi | Hi, Hi, Hi, Hi, Hi, Hi, Hi, Hi, Hi, Hi, |
One copy has no separators at all, which is the case that catches scripts built by testing with two.
"Characters" is three different numbers
Asking a string for its length in a browser gives you storage units, not letters. For plain text the two agree and nothing surprises anybody. For anything else there are three answers, and all three are correct answers to different questions.
| Text | Storage units | Code points | Visible glyphs |
|---|---|---|---|
Plain ASCII — Hello | 5 | 5 | 5 |
Precomposed e-acute — café | 4 | 4 | 4 |
e plus combining acute — café | 5 | 5 | 4 |
Thumbs up — 👍 | 2 | 1 | 1 |
Flag — 🇯🇵 | 4 | 2 | 1 |
Family — 👨👩👧 | 8 | 5 | 1 |
A family emoji is one thing you can see, five code points and eight units of storage. The uncomfortable pair is the two spellings of café: one uses a single precomposed é, the other an e followed by a combining accent. They render identically, they count differently, and nothing on screen distinguishes them. 4 of the 6 samples give at least two different answers.
Which number you want depends on where the text is going. A database column declared for 100 characters usually means code points; a message length limit usually means storage units; a person counting on screen means glyphs. The label above shows the raw count, and the visible count beside it whenever they disagree, rather than quietly picking one.
And the size guard was counting the wrong thing
There is a 2,000,000-character cap here to keep the browser responsive, and it used to be estimated as (text + separator) × copies. That ignores the numbering option, which prepends "1. ", "2. " and so on — a cost that grows with the number of digits.
| Request | Estimated | Actual | Verdict |
|---|---|---|---|
"Hello" × 10,000 | 60,000 | 59,999 | fine |
"Hello" × 10,000, numbered | 60,000 | 118,893 | fine |
"Hello" × 10,000, numbered | 50,000 | 108,894 | fine |
"x" × 300,000, numbered | 300,000 | 2,588,895 | let through, over the cap |
One character repeated 300,000 times with numbering on: the guard predicted 300,000 and the real output was 2,588,895. It sailed past the cap it was there to enforce, by a factor of more than eight. With numbering off the estimate was accurate to within one separator, which is why it went unnoticed.
The guard now computes the exact length rather than estimating it, which is cheap because it is arithmetic on how many digits the numbering takes — 38,894 for the numbers 1 to 10,000 — instead of building the string to find out. Blocking also clears the result now; it used to leave the previous output on screen beneath the error, describing inputs that were no longer there.
How to use
- Enter the text you want repeated.
- Set how many copies you need.
- Choose a separator and whether to number each copy.
- Copy or download the result.
Frequently asked questions
What is this actually useful for?
Generating test data, filling a template with placeholder rows, building repetitive markup or SQL statements, and stress-testing a field's character limit. It saves the tedium of a copy-and-paste loop and the off-by-one errors that reliably come with doing it by hand.
Can I number each repetition?
Yes. Numbering turns a repeated block into a genuine sequence, which is what makes the output useful as test data — a hundred identical rows tell you far less than a hundred distinguishable ones, particularly when you are trying to trace which record caused a failure.
Is there a limit on how many copies?
A practical one rather than a fixed one. Very large outputs make the browser sluggish and become awkward to select and copy. For anything genuinely enormous, generating the text in a script is a better approach than asking a browser tool to hold it all in memory.
How do I put each copy on its own line?
Use a newline as the separator. The distinction between a separator and a suffix matters here: a separator goes between copies, so a hundred copies produce ninety-nine separators and no stray blank line at the end.
Does this add a trailing separator?
No, deliberately. A trailing comma or newline after the final item is a persistent annoyance when the output is going into code, JSON or a data file, since it produces a syntax error or a phantom empty record. The separator appears only between copies.
Can I repeat text containing line breaks?
Yes — multi-line input is treated as a block and repeated whole. This is what makes the tool useful for template fragments such as an HTML table row, a JSON object, or a SQL insert statement, rather than just for single words.
Why would I need a separator other than a newline?
Because the output often has to be valid syntax rather than just readable. A comma and space builds a list for code, a pipe builds a Markdown table row, and an empty separator concatenates everything into one continuous string for testing how a field handles length.
🔒 This tool runs entirely in your browser. Nothing you enter is uploaded, logged, or stored.