CSV to Notion
Notion turns a pasted Markdown table into a real Notion table. This page produces that Markdown from your CSV, with the two characters that would otherwise break it handled: a pipe inside a cell is escaped, and a line break inside a cell becomes a <br> that Notion renders as a line break rather than as the end of the row.
Try an example loads a small sales table you can paste straight into a Notion page.
Why Markdown and not a CSV upload
Notion does import CSV files, and for a large dataset that is the right route. For anything under a few thousand rows the paste is better, for three reasons that have nothing to do with speed.
- An import creates a new database page. It arrives as its own top-level item that you then have to move, rename and possibly convert to an inline table. A paste lands exactly where your cursor is, inside the page you are already writing.
- An import guesses your column types and is frequently wrong about dates and about numbers with currency symbols. A pasted table is text in every column, which is often what you wanted for a table inside a document.
- An import is a round trip. Save the file, find it in the picker, wait, then tidy up. A paste is two keystrokes.
So this page produces the paste form. Put the cursor on an empty line in Notion, paste, and the Markdown becomes a table.
The two characters that break a Markdown table
A Markdown table's structure is entirely made of pipes and line breaks. A pipe inside a cell ends the cell early, shifting every value after it one column left. A line break inside a cell ends the row, turning one record into two malformed ones.
Both come up constantly in real data: a notes field, a description, an address.
CSV cell Naive Markdown What this page writes
pipe | inside | pipe | inside | | pipe \| inside |
line | line | line<br>break |
break break |
Backslashes are escaped before pipes, so a cell ending in a backslash does not eat the escape on the pipe that follows it. A note above the result tells you when any cell needed this treatment, so a table that looks different from your source is never a surprise.
Worked example
In:
region,product,units,revenue
EU,Widget,1240,50220.00
US,Widget,2115,85657.50
APAC,Gadget,190,45600.00
Out, ready for the clipboard:
| region | product | units | revenue |
| --- | --- | --- | --- |
| EU | Widget | 1240 | 50220.00 |
| US | Widget | 2115 | 85657.50 |
| APAC | Gadget | 190 | 45600.00 |
The separator row is what tells Notion this is a table rather than four lines of text with pipes in them, and it is why a Markdown table always needs a header. If your file has no header row, turn First row is headers off and columns called Column 1, Column 2 and so on are supplied, so the structure is valid and your first record stays a record.
Column widths are not padded, deliberately
Some Markdown writers pad every cell so the source lines up in a text editor. That is pleasant to read as source and it is the wrong choice here for two reasons: Notion strips it entirely on paste, so it buys nothing at the destination, and it inflates a wide table by a large fraction, which makes the clipboard payload bigger for no benefit.
If you want a padded Markdown table for a README or a pull request, CSV to Markdown is the page for that and it offers alignment as an option.
Where the row cap comes from
Two thousand rows by default. That is not a licence limit, it is where the paste stops being the fast route: Notion builds table blocks one at a time as it parses the paste, and past a couple of thousand rows the tab stalls noticeably while it works.
The cap is a text box, so you can raise it if you know what you are doing. Above it you get a note naming the number, and for a genuinely large table Notion's own CSV import is the better tool.
Frequently Asked Questions
How do I actually paste it?
Copy the output with the Copy button, open your Notion page, put the cursor on an empty line, and paste. Notion recognizes the Markdown table syntax and converts it to a real table block. If it pastes as plain text, you probably pasted inside an existing code block or an existing table cell; move the cursor to an empty line first.
Will the columns keep their types?
No. A pasted Markdown table gives you text columns, which for a table inside a document is usually what you want. If you need real Notion property types such as date, number or select, use Notion's CSV import to create a database instead, then set the types there.
What happens to a cell with a line break in it?
It becomes a <br>, which Notion renders as a line break inside the cell. A raw line break would end the table row, splitting one record into two broken ones. A note above the result tells you when any cell was treated this way.
My CSV has no header row.
Turn off "First row is headers". Markdown tables require a header row to be recognized as tables at all, so generic names are supplied and your first record stays a record rather than becoming the header.
How many rows can I paste?
Two thousand by default, and the cap is editable. That is where the paste stops being faster than an import: Notion creates the table blocks one at a time and the tab stalls past a couple of thousand. For a large table use Notion's own CSV import.
Can I go the other way, from Notion to CSV?
Notion exports a database as CSV from its own menu. Once you have that file, everything else on this site reads it: profile it, pivot it, or open it in the full app.
Does anything I paste leave my computer?
No. There is no upload endpoint on this page and no network request in the code that does the work. JavaScript in your own tab reads the text, processes it and hands back the result. Nothing is stored between visits either, so reloading gives you an empty box again. You can confirm it by opening your browser's network panel and watching it stay quiet while you work.
Straight into the page you are writing
Free, no account, no upload. Copy, put the cursor on an empty line, paste.
Back to the converter