diff --git a/docs-site/docs/recipes/read-table-rows.md b/docs-site/docs/recipes/read-table-rows.md
new file mode 100644
index 0000000..5362a20
--- /dev/null
+++ b/docs-site/docs/recipes/read-table-rows.md
@@ -0,0 +1,120 @@
+---
+description: "Read HTML table rows with Selenium Boot Locator.rows(), find rows by column value, assert cells, and handle short rows and group headings."
+id: read-table-rows
+title: Read table rows
+sidebar_label: Read table rows
+---
+
+# Read table rows
+
+Read an HTML table as data instead of walking its cells by hand. Call `rows()` on a
+locator that points at the `
`, and you get back one map per row, keyed by
+column header.
+
+## Read, find, and assert on rows
+
+Given a table like this:
+
+```html
+
+
+ | Last Name | First Name | Due |
+
+
+ | Smith | John | $50.00 |
+ | Doe | Jason | $100.00 |
+
+
+```
+
+read it, find a row by a column's value, and assert on a cell:
+
+```java title="AccountsTableTest.java"
+import com.seleniumboot.test.BaseTest;
+import java.util.List;
+import java.util.Map;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class AccountsTableTest extends BaseTest {
+
+ @Test
+ public void doeOwesOneHundred() {
+ open("/accounts");
+
+ // One map per row, keyed by column header:
+ // [{Last Name=Smith, First Name=John, Due=$50.00},
+ // {Last Name=Doe, First Name=Jason, Due=$100.00}]
+ List