diff --git a/.gitignore b/.gitignore
index 9daa824..210c9c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 .DS_Store
 node_modules
+build
diff --git a/Dockerfile b/Dockerfile
index d16b547..17c3020 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,7 +6,4 @@ RUN npm install && node ./index.js
 
 FROM caddy:2.9.1
 
-COPY img /usr/share/caddy/img
-COPY css /usr/share/caddy/css
-COPY stores.json robots.txt /usr/share/caddy/
-COPY --from=builder /src/index.html /usr/share/caddy/index.html
+COPY --from=builder /src/build /usr/share/caddy
diff --git a/index.html b/index.html
deleted file mode 100644
index 9759f11..0000000
--- a/index.html
+++ /dev/null
@@ -1,968 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <script
-      defer=""
-      data-domain="nycbookstores.org"
-      src="https://stats.yetaga.in/js/script.hash.outbound-links.js"
-    ></script>
-    <meta charset="utf-8" />
-    <meta http-equiv="x-ua-compatible" content="ie=edge" />
-    <title>
-      Independent Bookstores in New York City - Best Community Bookstores in NYC
-    </title>
-    <meta
-      name="google-site-verification"
-      content="hEfog9h0E3JQW91ZUZM5ayPb6DND0WbUa2_W8yTIuVw"
-    />
-    <link rel="icon" type="image/png" href="/img/favicon.png" />
-    <link rel="apple-touch-icon" href="/img/social.jpg" />
-    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <script src="https://api.mapbox.com/mapbox-gl-js/v2.13.0/mapbox-gl.js"></script>
-    <link
-      href="https://api.mapbox.com/mapbox-gl-js/v2.13.0/mapbox-gl.css"
-      rel="stylesheet"
-    />
-    <link
-      href="https://fonts.googleapis.com/css?family=Acme|Lato&amp;display=swap"
-      rel="stylesheet"
-    />
-    <link
-      media="screen"
-      rel="stylesheet"
-      type="text/css"
-      href="/css/site.css?1709780697849"
-    />
-    <meta
-      property="title"
-      name="title"
-      content="Independent Bookstores in New York City - Best Community Bookstores in NYC"
-    />
-    <meta
-      property="description"
-      name="description"
-      content="A guide to and map of every independent bookstore in New York City. We have a complete list of community bookstores in NYC with locations and descriptions."
-    />
-    <meta name="twitter:card" content="summary" />
-    <meta name="twitter:site" content="www.nycbookstores.org" />
-    <meta name="twitter:title" content="NYC Bookstores" />
-    <meta
-      name="twitter:description"
-      content="A Guide To The Many Independent Bookstores Of New York City"
-    />
-    <meta
-      name="twitter:image"
-      content="https://www.nycbookstores.org/img/social.jpg"
-    />
-    <meta property="og:url" content="https://www.nycbookstores.org/" />
-    <meta property="og:type" content="website" />
-    <meta property="og:title" content="NYC Bookstores" />
-    <meta
-      property="og:description"
-      content="A Guide To The Many Independent Bookstores Of New York City"
-    />
-    <meta
-      property="og:image"
-      content="https://www.nycbookstores.org/img/social.jpg"
-    />
-    <link rel="canonical" href="https://www.nycbookstores.org/" />
-  </head>
-  <body>
-    <div id="wrapper">
-      <h1>NYC Bookstores</h1>
-      <div>
-        <ul class="nav">
-          <li>
-            <h2 id="subhed">
-              The Many Independent Bookstores of New York City
-            </h2>
-          </li>
-          <li>
-            <a id="viewInfo" href="#info" onclick="event.preventDefault()"
-              >intro</a
-            >
-          </li>
-          <li>
-            <a
-              href="https://git.yetaga.in/alazyreader/nyc-bookstores/"
-              target="_blank"
-              >source</a
-            >
-          </li>
-          <li>
-            <a href="https://icosahedron.website/@lazyreader" target="_blank"
-              >@lazyreader</a
-            >
-          </li>
-        </ul>
-      </div>
-      <div class="container">
-        <div id="map"></div>
-        <div id="info">
-          <p>
-            New York City loves its independent bookstores. It
-            <a
-              href="https://www.nytimes.com/2006/10/15/nyregion/thecity/15book.html"
-              target="_blank"
-              >eulogizes those that have faded</a
-            >
-            and celebrates when new ventures are launched. And while the
-            historic
-            <a
-              href="https://untappedcities.com/2015/08/26/4th-avenue-the-history-of-nycs-book-row/"
-              target="_blank"
-              >Book Row may have passed away in the 80s</a
-            >, there are still many indie bookstores dotting the map, across all
-            five boroughs. Here, I have attempted to collect all of the
-            currently-open general-interest independent booksellers in NYC. Any
-            store with regular-ish hours (excluding religious booksellers and
-            appointment-only rare book sellers) is included.
-          </p>
-          <p>
-            While Manhattan and Brooklyn still lead the pack, Queens has a
-            respectable number of stores, and all five boroughs are represented,
-            with the Bronx and Staten Island both hosting lone independent
-            stores. Lower Manhattan has the highest density of booksellers.
-          </p>
-          <p>
-            The listings here are kept up-to-date to the best of my ability;
-            however, I make no promises about either the accuracy or reliability
-            of the information. If you spot an error, or I've missed a shop,
-            please let me know by
-            <a href="mailto:delta.mu.alpha@gmail.com" target="_blank">email</a>,
-            <a href="https://icosahedron.website/@lazyreader" target="_blank"
-              >mastodon</a
-            >, or
-            <a href="https://www.twitter.com/alazyreader" target="_blank"
-              >twitter</a
-            >. Originally based on the "<a
-              href="https://github.com/jlord/hack-spots"
-              target="_blank"
-              >Hack Spots</a
-            >" website by
-            <a href="https://www.twitter.com/jllord" target="_blank">@jllord</a>
-            (although I don't believe any of the actual underlying code still
-            survives at this point).
-          </p>
-          <p>
-            There are currently <span id="storeCount">118</span> stores indexed
-            on this page. Last updated
-            <span id="updatedOn">March 6, 2024</span>.
-          </p>
-          <details>
-            <summary>Recent Changes</summary>
-            <ul id="changesList">
-              <li>
-                January 28, 2024 - move Yu and Me back to its original location
-                (congrats!)
-              </li>
-              <li>
-                January 1, 2024 - Add Bibliotheque and The World's Borough
-                Bookshop
-              </li>
-              <li>
-                December 27, 2023 - add La Joie de Vivre, a French/English
-                bookstore in the Flatiron Distirct
-              </li>
-              <li>December 21, 2023 - add canonical link</li>
-            </ul>
-          </details>
-        </div>
-        <div id="selected"></div>
-      </div>
-
-      <div class="clearfix"></div>
-
-      <div class="container">
-        <div id="Stores">
-          <table>
-            <tbody>
-              <tr id="0" class="spotRow">
-                <td class="name">1804 Books</td>
-                <td>320 W 37th St, New York</td>
-              </tr>
-              <tr id="1" class="spotRow">
-                <td class="name">192 Books</td>
-                <td>192 10th Ave, New York</td>
-              </tr>
-              <tr id="2" class="spotRow">
-                <td class="name">Adanne</td>
-                <td>115 Ralph Ave, Brooklyn</td>
-              </tr>
-              <tr id="3" class="spotRow">
-                <td class="name">Aeon Bookstore</td>
-                <td>151 East Broadway, New York</td>
-              </tr>
-              <tr id="4" class="spotRow">
-                <td class="name">Alabaster Bookshop</td>
-                <td>122 4th Ave, New York</td>
-              </tr>
-              <tr id="5" class="spotRow">
-                <td class="name">Albertine Books</td>
-                <td>972 Fifth Ave, New York</td>
-              </tr>
-              <tr id="6" class="spotRow">
-                <td class="name">Archestratus</td>
-                <td>164 Huron St, Brooklyn</td>
-              </tr>
-              <tr id="7" class="spotRow">
-                <td class="name">Argosy Books</td>
-                <td>116 East 59th St, New York</td>
-              </tr>
-              <tr id="8" class="spotRow">
-                <td class="name">Astoria Bookshop</td>
-                <td>36-19 30th St, Astoria</td>
-              </tr>
-              <tr id="9" class="spotRow">
-                <td class="name">Berl's Brooklyn Poetry Shop</td>
-                <td>126A Front St, Brooklyn</td>
-              </tr>
-              <tr id="10" class="spotRow">
-                <td class="name">Better Read Than Dead</td>
-                <td>867 Broadway, Brooklyn</td>
-              </tr>
-              <tr id="11" class="spotRow">
-                <td class="name">Better Read Than Dead &amp; Burly Coffee</td>
-                <td>90 Kosciuszko St, Brooklyn</td>
-              </tr>
-              <tr id="12" class="spotRow">
-                <td class="name">Bibliotheque</td>
-                <td>54 Mercer St, New York</td>
-              </tr>
-              <tr id="13" class="spotRow">
-                <td class="name">Black Spring Books</td>
-                <td>672 Driggs Ave, Brooklyn</td>
-              </tr>
-              <tr id="14" class="spotRow">
-                <td class="name">Bluestockings Cooperative</td>
-                <td>116 Suffolk Street, New York</td>
-              </tr>
-              <tr id="15" class="spotRow">
-                <td class="name">Bonnie Slotnick Cookbooks</td>
-                <td>28 East 2nd St, New York</td>
-              </tr>
-              <tr id="16" class="spotRow">
-                <td class="name">Book Club Bar</td>
-                <td>197 E 3rd St, New York</td>
-              </tr>
-              <tr id="17" class="spotRow">
-                <td class="name">Book Culture</td>
-                <td>536 W 112th St, New York</td>
-              </tr>
-              <tr id="18" class="spotRow">
-                <td class="name">Book Culture LIC</td>
-                <td>26-09 Jackson Ave, Queens</td>
-              </tr>
-              <tr id="19" class="spotRow">
-                <td class="name">Book Culture on Broadway</td>
-                <td>2915 Broadway, New York</td>
-              </tr>
-              <tr id="20" class="spotRow">
-                <td class="name">Book Thug Nation</td>
-                <td>100 North 3rd St, Brooklyn</td>
-              </tr>
-              <tr id="21" class="spotRow">
-                <td class="name">Bookmarc</td>
-                <td>400 Bleecker St, New York</td>
-              </tr>
-              <tr id="22" class="spotRow">
-                <td class="name">BookMark Shoppe</td>
-                <td>8415 3rd Avenue, Brooklyn</td>
-              </tr>
-              <tr id="23" class="spotRow">
-                <td class="name">Bookoff</td>
-                <td>49 W 45nd St, New York</td>
-              </tr>
-              <tr id="24" class="spotRow">
-                <td class="name">Bookoff Brooklyn</td>
-                <td>934 3rd Ave, Brooklyn</td>
-              </tr>
-              <tr id="25" class="spotRow">
-                <td class="name">Books Are Magic (Montague St.)</td>
-                <td>122 Montague St, Brooklyn</td>
-              </tr>
-              <tr id="26" class="spotRow">
-                <td class="name">Books Are Magic (Smith St.)</td>
-                <td>225 Smith St, Brooklyn</td>
-              </tr>
-              <tr id="27" class="spotRow">
-                <td class="name">Books Of Wonder</td>
-                <td>42 West 17th St, New York</td>
-              </tr>
-              <tr id="28" class="spotRow">
-                <td class="name">Bravo's Book Nook</td>
-                <td>115 MacDougal St, New York</td>
-              </tr>
-              <tr id="29" class="spotRow">
-                <td class="name">Burnt Books</td>
-                <td>157 Huron St, Brooklyn</td>
-              </tr>
-              <tr id="30" class="spotRow">
-                <td class="name">Cafe con Libros</td>
-                <td>724 Prospect Place, Brooklyn</td>
-              </tr>
-              <tr id="31" class="spotRow">
-                <td class="name">Catland</td>
-                <td>985 Flushing Ave, Brooklyn</td>
-              </tr>
-              <tr id="32" class="spotRow">
-                <td class="name">Chartwell Booksellers</td>
-                <td>55 E 52nd St, New York</td>
-              </tr>
-              <tr id="33" class="spotRow">
-                <td class="name">Codex Books</td>
-                <td>1 Bleecker St, New York</td>
-              </tr>
-              <tr id="34" class="spotRow">
-                <td class="name">Community Bookstore</td>
-                <td>143 7th Ave, Brooklyn</td>
-              </tr>
-              <tr id="35" class="spotRow">
-                <td class="name">Cups and Books</td>
-                <td>2024 Bedford Ave, Brooklyn</td>
-              </tr>
-              <tr id="36" class="spotRow">
-                <td class="name">Dashwood Books</td>
-                <td>33 Bond St, New York</td>
-              </tr>
-              <tr id="37" class="spotRow">
-                <td class="name">Dear Friend Books</td>
-                <td>343A Tompkins Ave, Brooklyn</td>
-              </tr>
-              <tr id="38" class="spotRow">
-                <td class="name">Desert Island Comics</td>
-                <td>540 Metropolitan Ave, Brooklyn</td>
-              </tr>
-              <tr id="39" class="spotRow">
-                <td class="name">East Village Books</td>
-                <td>99 St. Mark's Place, New York</td>
-              </tr>
-              <tr id="40" class="spotRow">
-                <td class="name">ETG Book Cafe</td>
-                <td>208 Bay St, Staten Island</td>
-              </tr>
-              <tr id="41" class="spotRow">
-                <td class="name">Freebird Books</td>
-                <td>123 Columbia St, Brooklyn</td>
-              </tr>
-              <tr id="42" class="spotRow">
-                <td class="name">Greenlight Bookstore</td>
-                <td>686 Fulton St, Brooklyn</td>
-              </tr>
-              <tr id="43" class="spotRow">
-                <td class="name">Here's A Book Store</td>
-                <td>1964 Coney Island Ave, Brooklyn</td>
-              </tr>
-              <tr id="44" class="spotRow">
-                <td class="name">Hey Kids! Comics</td>
-                <td>157 Huron St, Brooklyn</td>
-              </tr>
-              <tr id="45" class="spotRow">
-                <td class="name">Housing Works Bookstore Café</td>
-                <td>126 Crosby St, New York</td>
-              </tr>
-              <tr id="46" class="spotRow">
-                <td class="name">Human Relations Books</td>
-                <td>1067 Flushing Ave, Brooklyn</td>
-              </tr>
-              <tr id="47" class="spotRow">
-                <td class="name">James Cummins Bookseller</td>
-                <td>699 Madison Ave, 7th Floor, New York</td>
-              </tr>
-              <tr id="48" class="spotRow">
-                <td class="name">Joanne Hendricks Cookbooks</td>
-                <td>488 Greenwich St, New York</td>
-              </tr>
-              <tr id="49" class="spotRow">
-                <td class="name">Karma Bookstore</td>
-                <td>136 East Third St, New York</td>
-              </tr>
-              <tr id="50" class="spotRow">
-                <td class="name">Kew &amp; Willow Books</td>
-                <td>81-63 Lefferts Boulevard, New York</td>
-              </tr>
-              <tr id="51" class="spotRow">
-                <td class="name">Kinokunya</td>
-                <td>1073 Avenue of the Americas, New York</td>
-              </tr>
-              <tr id="52" class="spotRow">
-                <td class="name">Kitchen Arts &amp; Letters</td>
-                <td>1435 Lexington Ave, New York</td>
-              </tr>
-              <tr id="53" class="spotRow">
-                <td class="name">La Joie de Vivre</td>
-                <td>145 W 27th St, New York</td>
-              </tr>
-              <tr id="54" class="spotRow">
-                <td class="name">Leaves Bookstore</td>
-                <td>140 Nassau Ave, Brooklyn</td>
-              </tr>
-              <tr id="55" class="spotRow">
-                <td class="name">Left Bank Books</td>
-                <td>41 Perry St, New York</td>
-              </tr>
-              <tr id="56" class="spotRow">
-                <td class="name">Lofty Pigeon Books</td>
-                <td>743 Church Ave, Brooklyn</td>
-              </tr>
-              <tr id="57" class="spotRow">
-                <td class="name">Logos Bookstore</td>
-                <td>1575 York Ave, New York</td>
-              </tr>
-              <tr id="58" class="spotRow">
-                <td class="name">Mast Books</td>
-                <td>72 Avenue A, New York</td>
-              </tr>
-              <tr id="59" class="spotRow">
-                <td class="name">McNally Jackson Books</td>
-                <td>134 Prince St, New York</td>
-              </tr>
-              <tr id="60" class="spotRow">
-                <td class="name">McNally Jackson Books City Point</td>
-                <td>445 Albee Square W, Unit G112, Brooklyn</td>
-              </tr>
-              <tr id="61" class="spotRow">
-                <td class="name">McNally Jackson Books Seaport</td>
-                <td>4 Fulton St, New York</td>
-              </tr>
-              <tr id="62" class="spotRow">
-                <td class="name">McNally Jackson Books Williamsburg</td>
-                <td>76 North 4th St, Brooklyn</td>
-              </tr>
-              <tr id="63" class="spotRow">
-                <td class="name">McNally Jackson Rockefeller Center</td>
-                <td>1 Rockefeller Plaza, New York</td>
-              </tr>
-              <tr id="64" class="spotRow">
-                <td class="name">Melville House Publishers</td>
-                <td>46 John St, Brooklyn</td>
-              </tr>
-              <tr id="65" class="spotRow">
-                <td class="name">Mercer Street Books &amp; Records</td>
-                <td>206 Mercer St, New York</td>
-              </tr>
-              <tr id="66" class="spotRow">
-                <td class="name">Mil Mundos Books</td>
-                <td>323 Linden St, Brooklyn</td>
-              </tr>
-              <tr id="67" class="spotRow">
-                <td class="name">Molasses Books</td>
-                <td>770 Hart St, Brooklyn</td>
-              </tr>
-              <tr id="68" class="spotRow">
-                <td class="name">Namaste Bookshop</td>
-                <td>2 W 14th St, New York</td>
-              </tr>
-              <tr id="69" class="spotRow">
-                <td class="name">P&amp;T Knitwear</td>
-                <td>180 Orchard St, New York</td>
-              </tr>
-              <tr id="70" class="spotRow">
-                <td class="name">Passageway Books</td>
-                <td>150 9th Ave, New York</td>
-              </tr>
-              <tr id="71" class="spotRow">
-                <td class="name">Pillow-Cat Books</td>
-                <td>328 East 9th St, New York</td>
-              </tr>
-              <tr id="72" class="spotRow">
-                <td class="name">Posman Books Chelsea Market</td>
-                <td>75 9th Avenue, New York</td>
-              </tr>
-              <tr id="73" class="spotRow">
-                <td class="name">POWERHOUSE @ IC</td>
-                <td>220 36th St, Building #2, Brooklyn</td>
-              </tr>
-              <tr id="74" class="spotRow">
-                <td class="name">POWERHOUSE Arena</td>
-                <td>28 Adams St, Brooklyn</td>
-              </tr>
-              <tr id="75" class="spotRow">
-                <td class="name">POWERHOUSE on 8th</td>
-                <td>1111 8th Ave, Brooklyn</td>
-              </tr>
-              <tr id="76" class="spotRow">
-                <td class="name">Printed Matter</td>
-                <td>231 11th Ave, New York</td>
-              </tr>
-              <tr id="77" class="spotRow">
-                <td class="name">Printed Matter St. Marks</td>
-                <td>38 St. Marks Pl, New York</td>
-              </tr>
-              <tr id="78" class="spotRow">
-                <td class="name">Quest Bookshop</td>
-                <td>240 E 53rd St, New York</td>
-              </tr>
-              <tr id="79" class="spotRow">
-                <td class="name">Quimby's Bookstore</td>
-                <td>536 Metropolitan Ave, Brooklyn</td>
-              </tr>
-              <tr id="80" class="spotRow">
-                <td class="name">Recirculation</td>
-                <td>876 Riverside Dr, New York</td>
-              </tr>
-              <tr id="81" class="spotRow">
-                <td class="name">Respect For Life Books-N-Things</td>
-                <td>537 Nostrand Ave, Brooklyn</td>
-              </tr>
-              <tr id="82" class="spotRow">
-                <td class="name">Revolution Books</td>
-                <td>437 Malcolm X Blvd, New York</td>
-              </tr>
-              <tr id="83" class="spotRow">
-                <td class="name">Rizzoli Bookstore</td>
-                <td>1133 Broadway, New York</td>
-              </tr>
-              <tr id="84" class="spotRow">
-                <td class="name">Shakespeare &amp; Company</td>
-                <td>939 Lexington Ave, New York</td>
-              </tr>
-              <tr id="85" class="spotRow">
-                <td class="name">
-                  Shakespeare &amp; Company (Manhattan Valley/Columbia
-                  University)
-                </td>
-                <td>2736 Broadway, New York</td>
-              </tr>
-              <tr id="86" class="spotRow">
-                <td class="name">
-                  Shakespeare &amp; Company (Upper West Side)
-                </td>
-                <td>2020 Broadway, New York</td>
-              </tr>
-              <tr id="87" class="spotRow">
-                <td class="name">Sister's Uptown Bookstore</td>
-                <td>1942 Amsterdam Ave, New York</td>
-              </tr>
-              <tr id="88" class="spotRow">
-                <td class="name">Spoonbill &amp; Sugartown, Booksellers</td>
-                <td>218 Bedford Ave, Brooklyn</td>
-              </tr>
-              <tr id="89" class="spotRow">
-                <td class="name">Standards Manual</td>
-                <td>212 Franklin Street, Brooklyn</td>
-              </tr>
-              <tr id="90" class="spotRow">
-                <td class="name">Strand Bookstore</td>
-                <td>828 Broadway, New York</td>
-              </tr>
-              <tr id="91" class="spotRow">
-                <td class="name">Sweet Pickle Books</td>
-                <td>47 Orchard St, New York</td>
-              </tr>
-              <tr id="92" class="spotRow">
-                <td class="name">Taylor &amp; Co. Books</td>
-                <td>1021 Cortelyou Rd, Brooklyn</td>
-              </tr>
-              <tr id="93" class="spotRow">
-                <td class="name">Terrace Books</td>
-                <td>242 Prospect Park West, Brooklyn</td>
-              </tr>
-              <tr id="94" class="spotRow">
-                <td class="name">The Austin Book Shop</td>
-                <td>104-29 Jamaica Ave, Richmond Hill</td>
-              </tr>
-              <tr id="95" class="spotRow">
-                <td class="name">The Book Cellar</td>
-                <td>1465 York Ave, New York</td>
-              </tr>
-              <tr id="96" class="spotRow">
-                <td class="name">The Center for Fiction</td>
-                <td>15 Lafayette Ave, Brooklyn</td>
-              </tr>
-              <tr id="97" class="spotRow">
-                <td class="name">The Corner Bookstore</td>
-                <td>1313 Madison Ave, New York</td>
-              </tr>
-              <tr id="98" class="spotRow">
-                <td class="name">The Drama Book Shop</td>
-                <td>266 W 39th St, New York</td>
-              </tr>
-              <tr id="99" class="spotRow">
-                <td class="name">The Lit. Bar</td>
-                <td>131 Alexander Ave, Bronx</td>
-              </tr>
-              <tr id="100" class="spotRow">
-                <td class="name">The Mysterious Bookshop</td>
-                <td>58 Warren St, New York</td>
-              </tr>
-              <tr id="101" class="spotRow">
-                <td class="name">The Ripped Bodice</td>
-                <td>218 5th Ave, Brooklyn</td>
-              </tr>
-              <tr id="102" class="spotRow">
-                <td class="name">The Strand At Columbus Ave</td>
-                <td>450 Columbus Ave, New York</td>
-              </tr>
-              <tr id="103" class="spotRow">
-                <td class="name">The Word Is Change</td>
-                <td>368 Tompkins Ave, Brooklyn</td>
-              </tr>
-              <tr id="104" class="spotRow">
-                <td class="name">The World's Borough Bookshop</td>
-                <td>3406 73rd St, Queens</td>
-              </tr>
-              <tr id="105" class="spotRow">
-                <td class="name">Three Lives &amp; Company</td>
-                <td>154 W 10th St, New York</td>
-              </tr>
-              <tr id="106" class="spotRow">
-                <td class="name">Topos Bookstore Cafe</td>
-                <td>788 Woodward Ave, Brooklyn</td>
-              </tr>
-              <tr id="107" class="spotRow">
-                <td class="name">Topos Too</td>
-                <td>59-22 Myrtle Ave, Queens</td>
-              </tr>
-              <tr id="108" class="spotRow">
-                <td class="name">Troubled Sleep Books</td>
-                <td>129 6th Ave, Brooklyn</td>
-              </tr>
-              <tr id="109" class="spotRow">
-                <td class="name">Turn The Page... Again</td>
-                <td>39-15a Bell Blvd, Flushing</td>
-              </tr>
-              <tr id="110" class="spotRow">
-                <td class="name">Unnameable Books</td>
-                <td>600 Vanderbilt Ave, Brooklyn</td>
-              </tr>
-              <tr id="111" class="spotRow">
-                <td class="name">Ursus Books</td>
-                <td>50 East 78th St, Suite 1C, New York</td>
-              </tr>
-              <tr id="112" class="spotRow">
-                <td class="name">Village Works</td>
-                <td>12 St. Marks Pl, New York</td>
-              </tr>
-              <tr id="113" class="spotRow">
-                <td class="name">Westsider Rare &amp; Used Books</td>
-                <td>2246 Broadway, New York</td>
-              </tr>
-              <tr id="114" class="spotRow">
-                <td class="name">Westsider Records</td>
-                <td>233 West 72nd St, New York</td>
-              </tr>
-              <tr id="115" class="spotRow">
-                <td class="name">Word Bookstore</td>
-                <td>126 Franklin St, Brooklyn</td>
-              </tr>
-              <tr id="116" class="spotRow">
-                <td class="name">Word Up Books</td>
-                <td>2113 Amsterdam Ave, New York</td>
-              </tr>
-              <tr id="117" class="spotRow">
-                <td class="name">Yu and Me Books</td>
-                <td>44 Mulberry St, New York</td>
-              </tr>
-            </tbody>
-          </table>
-        </div>
-      </div>
-    </div>
-    <!-- end wrapper -->
-
-    <script>
-      mapboxgl.accessToken =
-        "pk.eyJ1IjoiYWxhenlyZWFkZXIiLCJhIjoiY2lucDZhb2JxMHp6MHRxa2pvaTFoOWpuZyJ9.DILGYYxxt7A-A_lHHwp6tQ";
-      var map = new mapboxgl.Map({
-        container: "map",
-        style: "mapbox://styles/mapbox/basic-v9",
-        center: [-73.957292, 40.729071], // arbitrary center point
-        zoom: 9,
-        minZoom: 9,
-        maxZoom: 17,
-        dragRotate: false,
-      });
-
-      var popup = new mapboxgl.Popup({
-        closeOnClick: false,
-        closeButton: false,
-      });
-
-      function TableViewTemplate(rows) {
-        table = "<table>";
-        rows.forEach((row) => {
-          table = table + TableRowTemplate(row);
-        });
-        return table + "</table>";
-      }
-
-      function TableRowTemplate({ rowNumber, name, address, city }) {
-        return `<tr id="${rowNumber}" class="spotRow">
-          <td class="name">${name}</td><td>${address}, ${city}</td>
-        </tr>`;
-      }
-
-      function SelectedStoreTemplate({
-        name,
-        address,
-        city,
-        postcode,
-        website,
-        events,
-        cafe,
-        description,
-      }) {
-        const isAppleIsh = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform);
-        return `
-          <h2>${name}</h2>
-          <p class="address">${address}</p>
-          <p></p>
-          <p class="address">
-            ${city}, NY ${postcode}
-          </p>
-          <p>
-            View in:
-            <a
-              href="https://maps.google.com/maps?q=${encodeURIComponent(
-                name
-              )}+${address},${city},NY"
-              target="_blank"
-              >Google Maps</a
-            >
-            ${
-              isAppleIsh
-                ? `
-            <a
-              href="http://maps.apple.com/?q=${encodeURIComponent(
-                name
-              )}&address=${address},${city},NY"
-              target="_blank"
-              >Apple Maps</a
-            >`
-                : ""
-            }
-          </p>
-          <ul>
-            ${
-              website
-                ? `<li><a href="${website}" target="_blank">${cleanWebsite(
-                    website
-                  )}</a></li>`
-                : ""
-            }
-            <li class="storeDetails">Events: ${events}</li>
-            <li class="storeDetails">Caf&eacute;: ${cafe}</li>
-          </ul>
-          ${description ? `<p class="description">${description}</p>` : ""}`;
-      }
-
-      function hideElementById(id) {
-        const element = document.getElementById(id);
-        if (element !== undefined) {
-          element.classList.add("hidden");
-        }
-      }
-
-      function showElementById(id) {
-        const element = document.getElementById(id);
-        if (element !== undefined) {
-          element.classList.remove("hidden");
-        }
-      }
-
-      function setContent(id, html) {
-        const element = document.getElementById(id);
-        if (element !== undefined) {
-          element.innerHTML = html;
-        }
-      }
-
-      document.addEventListener("DOMContentLoaded", function () {
-        fetch("./stores.json")
-          .then((resp) => {
-            return resp.json();
-          })
-          .then((data) => {
-            data.sort(function (a, b) {
-              var aname = a.name.toLowerCase();
-              var bname = b.name.toLowerCase();
-              return aname === bname ? 0 : +(aname > bname) || -1;
-            });
-            data.forEach((value, key) => {
-              value.rowNumber = key;
-              value.slug = slugify(value.name);
-            });
-            setContent("storeCount", data.length);
-            window.data = data;
-            loadMap(data);
-          })
-          .catch((err) => {
-            // we'll live with the static cache!
-            console.log(err);
-          });
-      });
-
-      window.addEventListener(
-        "hashchange",
-        function (e) {
-          updateViewBySlug(e.newURL.split("#")[1]);
-        },
-        false
-      );
-
-      function updateHash(slug) {
-        history.pushState(null, null, "#" + slug);
-      }
-
-      function slugify(str) {
-        return str
-          .toLowerCase()
-          .replace(/é/g, "e")
-          .replace(/&/g, " and ")
-          .replace(/ /g, "-")
-          .replace(/[']+/g, "")
-          .replace(/[^\w-]+/g, "-")
-          .replace(/-+/g, "-")
-          .replace(/^-|-$/g, "");
-      }
-
-      function cleanWebsite(str) {
-        return str
-          .toLowerCase()
-          .replace(/^https?:\/\//g, "")
-          .replace(/^www./g, "")
-          .replace(/\/$/g, "");
-      }
-
-      function getStoreBySlug(slug) {
-        var ret = false;
-        window.data.forEach((value, key) => {
-          if (value.slug === slug) {
-            ret = value;
-            return false;
-          }
-        });
-        return ret;
-      }
-
-      function updateViewBySlug(slug) {
-        if (slug === "info" || slug === undefined) {
-          showInfo(false);
-        } else {
-          var store = getStoreBySlug(slug);
-          if (store) {
-            updateSelectedStore(store, false);
-          }
-        }
-      }
-
-      function boundingBox(point) {
-        // add some buffer to a point to give the user some leeway
-        return [
-          [point.x - 5, point.y - 5],
-          [point.x + 5, point.y + 5],
-        ];
-      }
-
-      function updateSelectedStore(store, pushState = false) {
-        map.flyTo({ center: [store.long, store.lat], zoom: 12 });
-
-        popup.setLngLat([store.long, store.lat]).setHTML(store.name).addTo(map);
-
-        hideElementById("info");
-        setContent("selected", SelectedStoreTemplate(store));
-        showElementById("selected");
-        if (pushState) {
-          updateHash(store.slug);
-        }
-      }
-
-      function showInfo(pushState = true) {
-        hideElementById("selected");
-        popup.remove();
-        showElementById("info");
-        if (pushState) {
-          updateHash("info");
-        }
-      }
-
-      function loadMap(data) {
-        var geolocate = new mapboxgl.GeolocateControl();
-
-        var points = [];
-        data.forEach((value, key) => {
-          points.push({
-            type: "Feature",
-            geometry: {
-              type: "Point",
-              coordinates: [value.long, value.lat],
-            },
-            properties: value,
-          });
-        });
-        map.on("load", function () {
-          map.addLayer({
-            id: "stores",
-            type: "circle",
-            source: {
-              type: "geojson",
-              data: {
-                type: "FeatureCollection",
-                features: points,
-              },
-            },
-            paint: {
-              "circle-radius": 5,
-              "circle-color": "#B9FCFC",
-              "circle-stroke-width": 2,
-              "circle-stroke-color": "#000000",
-            },
-          });
-          map.addControl(new mapboxgl.NavigationControl(), "top-left");
-          map.addControl(geolocate, "top-right");
-          updateViewBySlug(window.location.hash.split("#")[1]);
-        });
-
-        map.on("click", function (e) {
-          if (!map.getLayer("stores")) {
-            return;
-          }
-
-          popup.remove();
-          // Use queryRenderedFeatures to get features at a click event's point
-          var features = map.queryRenderedFeatures(boundingBox(e.point), {
-            layers: ["stores"],
-          });
-          // fly to the location of the click event
-          if (features.length) {
-            var store = features[0];
-            // Get coordinates from the symbol and center the map on those coordinates
-            updateSelectedStore(store.properties, true);
-          }
-        });
-
-        // indicate that the symbols are clickable by changing the cursor style to 'pointer'.
-        map.on("mousemove", function (e) {
-          if (!map.getLayer("stores")) {
-            return;
-          }
-          var features = map.queryRenderedFeatures(boundingBox(e.point), {
-            layers: ["stores"],
-          });
-          map.getCanvas().style.cursor = features.length ? "pointer" : "";
-        });
-
-        geolocate.on("geolocate", function (e) {
-          map.setZoom(14);
-          popup
-            .setLngLat([e.coords.longitude, e.coords.latitude])
-            .setHTML("Current Location")
-            .addTo(map);
-        });
-
-        setContent("Stores", TableViewTemplate(data));
-        document.querySelectorAll("#Stores tbody tr").forEach((element) => {
-          element.addEventListener("click", () => {
-            updateSelectedStore(data[element.id], true);
-            document
-              .getElementById("subhed")
-              .scrollIntoView({ behavior: "smooth" });
-          });
-        });
-
-        document.getElementById("viewInfo").addEventListener("click", showInfo);
-      }
-    </script>
-  </body>
-</html>
diff --git a/index.js b/index.js
index d945d19..7c5bd8c 100644
--- a/index.js
+++ b/index.js
@@ -1,8 +1,52 @@
 import { load } from "cheerio";
-import { readFile, writeFile } from "fs";
+import { readFile, writeFileSync, mkdirSync, cpSync, rmSync } from "fs";
 import process from "child_process";
 import stores from "./stores.json" with { type: "json" };
 
+function mkDir(path) {
+  try {
+    return mkdirSync(path)
+  } catch (err) {
+    if (err.code !== 'EEXIST') throw err
+  }
+}
+
+function writeFile(path, content) {
+  try {
+    writeFileSync(path, content);
+  } catch (err) {
+    if (err) throw err;
+  }
+   console.log(`${path} updated.`);
+}
+
+function slugify(str) {
+  return str
+    .toLowerCase()
+    .replace(/é/g, "e")
+    .replace(/&/g, " and ")
+    .replace(/ /g, "-")
+    .replace(/[']+/g, "")
+    .replace(/[^\w-]+/g, "-")
+    .replace(/-+/g, "-")
+    .replace(/^-|-$/g, "");
+}
+
+function cleanWebsite(str) {
+  return str
+    .toLowerCase()
+    .replace(/^https?:\/\//g, "")
+    .replace(/^www./g, "")
+    .replace(/\/$/g, "");
+}
+
+function metaDescription({ name, meta, description }) {
+  if (meta && (meta.length > 155 || meta.length < 145 && meta.length !== 0)) {
+    console.log(`warning: meta tag for ${name} is invalid: 145/${meta.length}/155`)
+  }
+  return meta || description.length > 155 ? description.slice(0, 153) + "..." : description || "A guide to and map of every independent bookstore in New York City. We have a complete list of community bookstores in NYC with locations and descriptions."
+}
+
 function GetRecentChanges() {
   const res = process
     .execSync('git log -15 --pretty=format:"%ct %s"')
@@ -44,15 +88,67 @@ function TableViewTemplate(rows) {
   return table + "</table>";
 }
 
-function TableRowTemplate({ rowNumber, name, address, city }) {
+function TableRowTemplate({ rowNumber, name, slug, address, city }) {
   return `
   <tr id="${rowNumber}" class="spotRow">
-    <td class="name">${name}</td>
-    <td>${address}, ${city}</td>
+    <td class="name"><a href="/${slugify(name)}/">${name}</a></td>
+    <td><a href="/${slugify(name)}/">${address}, ${city}</a></td>
   </tr>`;
 }
 
-readFile("./index.html", function (err, data) {
+function TitleTemplate({ name }) {
+  return `${name} | Independent Bookstores in New York City - Best Community Bookstores in NYC`;
+}
+
+function SelectedStoreTemplate({
+  name,
+  address,
+  city,
+  postcode,
+  website,
+  events,
+  cafe,
+  description,
+}) {
+  return `
+    <h2>${name}</h2>
+    <p class="address">${address}</p>
+    <p></p>
+    <p class="address">
+      ${city}, NY ${postcode}
+    </p>
+    <p>
+      View in:
+      <a
+        href="https://maps.google.com/maps?q=${encodeURIComponent(
+          name
+        )}+${address},${city},NY"
+        target="_blank"
+        >Google Maps</a
+      >
+      <a
+        href="http://maps.apple.com/?q=${encodeURIComponent(
+          name
+        )}&address=${address},${city},NY"
+        target="_blank"
+        >Apple Maps</a
+      >
+    </p>
+    <ul>
+      ${
+        website
+          ? `<li><a href="${website}" target="_blank">${cleanWebsite(
+              website
+            )}</a></li>`
+          : ""
+      }
+      <li class="storeDetails">Events: ${events}</li>
+      <li class="storeDetails">Caf&eacute;: ${cafe}</li>
+    </ul>
+    ${description ? `<p class="description">${description}</p>` : ""}`;
+}
+
+readFile("./index.tmpl.html", function (err, data) {
   const changeList = GetRecentChanges();
   if (err) {
     throw err;
@@ -77,8 +173,26 @@ readFile("./index.html", function (err, data) {
   $("#changesList").html(ChangeLog(changeList));
   const cssurl = $("link[type='text/css']").attr("href").split("?")[0];
   $("link[type='text/css']").attr("href", cssurl + "?" + new Date().getTime());
-  writeFile("./index.html", $.html(), (err) => {
-    if (err) throw err;
-    console.log("Default view updated.");
+
+  rmSync("./build", { recursive: true, force: true });
+
+  mkDir("./build")
+  
+  writeFile("./build/index.html", $.html())
+
+  cpSync("./site.css", "./build/site.css");
+  cpSync("./robots.txt", "./build/robots.txt");
+  cpSync("./img", "./build/img", {recursive: true});
+  cpSync("./stores.json", "./build/stores.json");
+
+  stores.forEach((store) => {
+    $("#selected").html(SelectedStoreTemplate(store));
+    $("#info").addClass("hidden");
+    let title = TitleTemplate(store);
+    $("title").html(title);
+    $("meta[name='title']").attr("content", title);
+    $("meta[name='description']").attr("content", metaDescription(store));
+    mkDir(`./build/${slugify(store.name)}`);
+    writeFile(`./build/${slugify(store.name)}/index.html`, $.html());
   });
 });
diff --git a/index.tmpl.html b/index.tmpl.html
new file mode 100644
index 0000000..7e2ff01
--- /dev/null
+++ b/index.tmpl.html
@@ -0,0 +1,469 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <script
+      defer=""
+      data-domain="nycbookstores.org"
+      src="https://stats.yetaga.in/js/script.outbound-links.js"
+    ></script>
+    <meta charset="utf-8" />
+    <meta http-equiv="x-ua-compatible" content="ie=edge" />
+    <title>
+      Independent Bookstores in New York City - Best Community Bookstores in NYC
+    </title>
+    <meta
+      name="google-site-verification"
+      content="hEfog9h0E3JQW91ZUZM5ayPb6DND0WbUa2_W8yTIuVw"
+    />
+    <link rel="icon" type="image/png" href="/img/favicon.png" />
+    <link rel="apple-touch-icon" href="/img/social.jpg" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <script src="https://api.mapbox.com/mapbox-gl-js/v2.13.0/mapbox-gl.js"></script>
+    <link
+      href="https://api.mapbox.com/mapbox-gl-js/v2.13.0/mapbox-gl.css"
+      rel="stylesheet"
+    />
+    <link
+      href="https://fonts.googleapis.com/css?family=Acme|Lato&amp;display=swap"
+      rel="stylesheet"
+    />
+    <link
+      media="screen"
+      rel="stylesheet"
+      type="text/css"
+      href="/site.css?1734659401621"
+    />
+    <meta
+      property="title"
+      name="title"
+      content="Independent Bookstores in New York City - Best Community Bookstores in NYC"
+    />
+    <meta
+      property="description"
+      name="description"
+      content="A guide to and map of every independent bookstore in New York City. We have a complete list of community bookstores in NYC with locations and descriptions."
+    />
+    <meta name="twitter:card" content="summary" />
+    <meta name="twitter:site" content="www.nycbookstores.org" />
+    <meta name="twitter:title" content="NYC Bookstores" />
+    <meta
+      name="twitter:description"
+      content="A Guide To The Many Independent Bookstores Of New York City"
+    />
+    <meta
+      name="twitter:image"
+      content="https://www.nycbookstores.org/img/social.jpg"
+    />
+    <meta property="og:url" content="https://www.nycbookstores.org/" />
+    <meta property="og:type" content="website" />
+    <meta property="og:title" content="NYC Bookstores" />
+    <meta
+      property="og:description"
+      content="A Guide To The Many Independent Bookstores Of New York City"
+    />
+    <meta
+      property="og:image"
+      content="https://www.nycbookstores.org/img/social.jpg"
+    />
+    <link rel="canonical" href="https://www.nycbookstores.org/" />
+  </head>
+  <body>
+    <div id="wrapper">
+      <h1>NYC Bookstores</h1>
+      <div>
+        <ul class="nav">
+          <li>
+            <h2 id="subhed">
+              The Many Independent Bookstores of New York City
+            </h2>
+          </li>
+          <li>
+            <a id="viewInfo" href="/">intro</a>
+          </li>
+          <li>
+            <a
+              href="https://git.yetaga.in/alazyreader/nyc-bookstores/"
+              target="_blank"
+              >source</a
+            >
+          </li>
+          <li>
+            <a href="https://icosahedron.website/@lazyreader" target="_blank"
+              >@lazyreader</a
+            >
+          </li>
+        </ul>
+      </div>
+      <div class="container">
+        <div id="map"></div>
+        <div id="info">
+          <p>
+            New York City loves its independent bookstores. It
+            <a
+              href="https://www.nytimes.com/2006/10/15/nyregion/thecity/15book.html"
+              target="_blank"
+              >eulogizes those that have faded</a
+            >
+            and celebrates when new ventures are launched. And while the
+            historic
+            <a
+              href="https://untappedcities.com/2015/08/26/4th-avenue-the-history-of-nycs-book-row/"
+              target="_blank"
+              >Book Row may have passed away in the 80s</a
+            >, there are still many indie bookstores dotting the map, across all
+            five boroughs. Here, I have attempted to collect all of the
+            currently-open general-interest independent booksellers in NYC. Any
+            store with regular-ish hours (excluding religious booksellers and
+            appointment-only rare book sellers) is included.
+          </p>
+          <p>
+            While Manhattan and Brooklyn still lead the pack, Queens has a
+            respectable number of stores, and all five boroughs are represented,
+            with the Bronx and Staten Island both hosting lone independent
+            stores. Lower Manhattan has the highest density of booksellers.
+          </p>
+          <p>
+            The listings here are kept up-to-date to the best of my ability;
+            however, I make no promises about either the accuracy or reliability
+            of the information. If you spot an error, or I've missed a shop,
+            please let me know by
+            <a href="mailto:delta.mu.alpha@gmail.com" target="_blank">email</a>,
+            <a href="https://icosahedron.website/@lazyreader" target="_blank"
+              >mastodon</a
+            >, or
+            <a href="https://www.twitter.com/alazyreader" target="_blank"
+              >twitter</a
+            >. Originally based on the "<a
+              href="https://github.com/jlord/hack-spots"
+              target="_blank"
+              >Hack Spots</a
+            >" website by
+            <a href="https://www.twitter.com/jllord" target="_blank">@jllord</a>
+            (although I don't believe any of the actual underlying code still
+            survives at this point).
+          </p>
+          <p>
+            There are currently <span id="storeCount">121</span> stores indexed
+            on this page. Last updated
+            <span id="updatedOn">December 19, 2024</span>.
+          </p>
+          <details>
+            <summary>Recent Changes</summary>
+            <ul id="changesList"></ul>
+          </details>
+        </div>
+        <div id="selected"></div>
+      </div>
+
+      <div class="clearfix"></div>
+
+      <div class="container">
+        <div id="Stores">
+          <table>
+            <tbody></tbody>
+          </table>
+        </div>
+      </div>
+    </div>
+    <!-- end wrapper -->
+
+    <script>
+      mapboxgl.accessToken =
+        "pk.eyJ1IjoiYWxhenlyZWFkZXIiLCJhIjoiY2lucDZhb2JxMHp6MHRxa2pvaTFoOWpuZyJ9.DILGYYxxt7A-A_lHHwp6tQ";
+      var map = new mapboxgl.Map({
+        container: "map",
+        style: "mapbox://styles/mapbox/basic-v9",
+        center: [-73.957292, 40.729071], // arbitrary center point
+        zoom: 9,
+        minZoom: 9,
+        maxZoom: 17,
+        dragRotate: false,
+      });
+
+      var popup = new mapboxgl.Popup({
+        closeOnClick: false,
+        closeButton: false,
+      });
+
+      function TitleTemplate({ name }) {
+        return `${name} | Independent Bookstores in New York City - Best Community Bookstores in NYC`;
+      }
+
+      function TableViewTemplate(rows) {
+        table = "<table>";
+        rows.forEach((row) => {
+          table = table + TableRowTemplate(row);
+        });
+        return table + "</table>";
+      }
+
+      function TableRowTemplate({ rowNumber, name, address, city }) {
+        return `<tr id="${rowNumber}" class="spotRow">
+          <td class="name">${name}</td><td>${address}, ${city}</td>
+        </tr>`;
+      }
+
+      function SelectedStoreTemplate({
+        name,
+        address,
+        city,
+        postcode,
+        website,
+        events,
+        cafe,
+        description,
+      }) {
+        const isAppleIsh = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform);
+        return `
+          <h2>${name}</h2>
+          <p class="address">${address}</p>
+          <p></p>
+          <p class="address">
+            ${city}, NY ${postcode}
+          </p>
+          <p>
+            View in:
+            <a
+              href="https://maps.google.com/maps?q=${encodeURIComponent(
+                name
+              )}+${address},${city},NY"
+              target="_blank"
+              >Google Maps</a
+            >
+            ${
+              isAppleIsh
+                ? `
+            <a
+              href="http://maps.apple.com/?q=${encodeURIComponent(
+                name
+              )}&address=${address},${city},NY"
+              target="_blank"
+              >Apple Maps</a
+            >`
+                : ""
+            }
+          </p>
+          <ul>
+            ${
+              website
+                ? `<li><a href="${website}" target="_blank">${cleanWebsite(
+                    website
+                  )}</a></li>`
+                : ""
+            }
+            <li class="storeDetails">Events: ${events}</li>
+            <li class="storeDetails">Caf&eacute;: ${cafe}</li>
+          </ul>
+          ${description ? `<p class="description">${description}</p>` : ""}`;
+      }
+
+      function hideElementById(id) {
+        const element = document.getElementById(id);
+        if (element !== undefined) {
+          element.classList.add("hidden");
+        }
+      }
+
+      function showElementById(id) {
+        const element = document.getElementById(id);
+        if (element !== undefined) {
+          element.classList.remove("hidden");
+        }
+      }
+
+      function setContent(id, html) {
+        const element = document.getElementById(id);
+        if (element !== undefined) {
+          element.innerHTML = html;
+        }
+      }
+
+      function setTitle(string) {
+        const element = document.getElementsByTagName("title");
+        if (element !== undefined && element.length === 1) {
+          element[0].innerText = string;
+        }
+      }
+
+      document.addEventListener("DOMContentLoaded", function () {
+        if (window.location.hash !== "") {
+          updateLocation(window.location.hash.substring(1));
+        }
+
+        fetch("/stores.json")
+          .then((resp) => {
+            return resp.json();
+          })
+          .then((data) => {
+            data.sort(function (a, b) {
+              var aname = a.name.toLowerCase();
+              var bname = b.name.toLowerCase();
+              return aname === bname ? 0 : +(aname > bname) || -1;
+            });
+            data.forEach((value, key) => {
+              value.rowNumber = key;
+              value.slug = slugify(value.name);
+            });
+            setContent("storeCount", data.length);
+            window.data = data;
+            loadMap(data);
+          })
+          .catch((err) => {
+            // we'll live with the static cache!
+            console.log(err);
+          });
+      });
+
+      function updateLocation(slug) {
+        history.pushState(null, null, `/${slug}`);
+      }
+
+      function slugify(str) {
+        return str
+          .toLowerCase()
+          .replace(/é/g, "e")
+          .replace(/&/g, " and ")
+          .replace(/ /g, "-")
+          .replace(/[']+/g, "")
+          .replace(/[^\w-]+/g, "-")
+          .replace(/-+/g, "-")
+          .replace(/^-|-$/g, "");
+      }
+
+      function cleanWebsite(str) {
+        return str
+          .toLowerCase()
+          .replace(/^https?:\/\//g, "")
+          .replace(/^www./g, "")
+          .replace(/\/$/g, "");
+      }
+
+      function getStoreBySlug(slug) {
+        var ret = false;
+        window.data.forEach((value, key) => {
+          if (value.slug === slug) {
+            ret = value;
+            return false;
+          }
+        });
+        return ret;
+      }
+
+      function updateViewBySlug(slug) {
+        if (slug === undefined) {
+          showInfo(false);
+        } else {
+          var store = getStoreBySlug(slug);
+          if (store) {
+            updateSelectedStore(store, false);
+          }
+        }
+      }
+
+      function boundingBox(point) {
+        // add some buffer to a point to give the user some leeway
+        return [
+          [point.x - 5, point.y - 5],
+          [point.x + 5, point.y + 5],
+        ];
+      }
+
+      function updateSelectedStore(store, pushState = false) {
+        map.flyTo({ center: [store.long, store.lat], zoom: 12 });
+
+        popup.setLngLat([store.long, store.lat]).setHTML(store.name).addTo(map);
+
+        hideElementById("info");
+        setContent("selected", SelectedStoreTemplate(store));
+        showElementById("selected");
+        setTitle(TitleTemplate(store));
+        if (pushState) {
+          updateLocation(store.slug);
+        }
+      }
+
+      function showInfo(pushState = true) {
+        hideElementById("selected");
+        popup.remove();
+        showElementById("info");
+        if (pushState) {
+          updateLocation("info");
+        }
+      }
+
+      function loadMap(data) {
+        var geolocate = new mapboxgl.GeolocateControl();
+
+        var points = [];
+        data.forEach((value, key) => {
+          points.push({
+            type: "Feature",
+            geometry: {
+              type: "Point",
+              coordinates: [value.long, value.lat],
+            },
+            properties: value,
+          });
+        });
+        map.on("load", function () {
+          map.addLayer({
+            id: "stores",
+            type: "circle",
+            source: {
+              type: "geojson",
+              data: {
+                type: "FeatureCollection",
+                features: points,
+              },
+            },
+            paint: {
+              "circle-radius": 5,
+              "circle-color": "#B9FCFC",
+              "circle-stroke-width": 2,
+              "circle-stroke-color": "#000000",
+            },
+          });
+          map.addControl(new mapboxgl.NavigationControl(), "top-left");
+          map.addControl(geolocate, "top-right");
+          updateViewBySlug(window.location.pathname.split("/")[1]);
+        });
+
+        map.on("click", function (e) {
+          if (!map.getLayer("stores")) {
+            return;
+          }
+          popup.remove();
+          // Use queryRenderedFeatures to get features at a click event's point
+          var features = map.queryRenderedFeatures(boundingBox(e.point), {
+            layers: ["stores"],
+          });
+          // fly to the location of the click event
+          if (features.length) {
+            var store = features[0];
+            // Get coordinates from the symbol and center the map on those coordinates
+            updateSelectedStore(store.properties, true);
+          }
+        });
+
+        // indicate that the symbols are clickable by changing the cursor style to 'pointer'.
+        map.on("mousemove", function (e) {
+          if (!map.getLayer("stores")) {
+            return;
+          }
+          var features = map.queryRenderedFeatures(boundingBox(e.point), {
+            layers: ["stores"],
+          });
+          map.getCanvas().style.cursor = features.length ? "pointer" : "";
+        });
+
+        geolocate.on("geolocate", function (e) {
+          map.setZoom(14);
+          popup
+            .setLngLat([e.coords.longitude, e.coords.latitude])
+            .setHTML("Current Location")
+            .addTo(map);
+        });
+      }
+    </script>
+  </body>
+</html>
diff --git a/css/site.css b/site.css
similarity index 99%
rename from css/site.css
rename to site.css
index 5721fc9..be3d211 100644
--- a/css/site.css
+++ b/site.css
@@ -180,7 +180,7 @@ ul.nav li a:hover {
   cursor: pointer;
 }
 #Stores tr td {
-  padding: 4px 10px;
+  padding: 4px 4px 12px;
 }
 #Stores tr:not(:last-child) td {
   border-bottom: 1px #ddd solid;
diff --git a/stores.json b/stores.json
index 18f2ae9..1420118 100644
--- a/stores.json
+++ b/stores.json
@@ -11,7 +11,8 @@
     "country": "USA",
     "website": "https://www.housingworks.org/locations/bookstore-cafe",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": "Housing Works Bookstore Café, in SoHo, Manhattan, is a well-known used bookstore and cafe that funds charity work for unhoused New Yorkers with HIV/AIDS."
   },
   {
     "name": "McNally Jackson Books",
@@ -25,7 +26,8 @@
     "country": "USA",
     "website": "https://www.mcnallyjackson.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "McNally Jackson Books, in Soho, Manhattan, is a stalwart indie bookstore with broad selection of genres, including international and small-press titles."
   },
   {
     "name": "Word Bookstore",
@@ -39,7 +41,8 @@
     "country": "USA",
     "website": "https://www.wordbookstores.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Word Bookstore, in Greenpoint, Brooklyn, is a community bookstore stocking fiction, non-fiction, and children's books, and hosting events in the basement."
   },
   {
     "name": "Astoria Bookshop",
@@ -53,7 +56,8 @@
     "country": "USA",
     "website": "https://www.astoriabookshop.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Astoria Bookshop, in Astoria, Queens, is a general-interest local bookstore with a large children's department. It also hosts book clubs and signings."
   },
   {
     "name": "POWERHOUSE Arena",
@@ -67,7 +71,8 @@
     "country": "USA",
     "website": "https://www.powerhousebookstores.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "POWERHOUSE Arena, in Dumbo, Brooklyn, is a combination event space/bookstore. It stocks a selection of current fiction and non-fiction and hosts signings."
   },
   {
     "name": "Mercer Street Books & Records",
@@ -81,7 +86,8 @@
     "country": "USA",
     "website": "http://www.mercerstreetbooks.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Mercer Street Books & Records, near NYU in Manhattan, is a small but crowded used bookseller with an eclectic selection of books, including textbooks."
   },
   {
     "name": "Mast Books",
@@ -95,7 +101,8 @@
     "country": "USA",
     "website": "https://www.mastbooks.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Mast Books, in the East Village in Manhattan, focuses on selling used copies of art, music, photography, and fiction. Also exhibits punk ephemera."
   },
   {
     "name": "The Mysterious Bookshop",
@@ -103,13 +110,14 @@
     "city": "New York",
     "state": "NY",
     "postcode": "10007",
-    "description": "Mysterious Bookshop sells new, used, and vintage mysteries and thrillers, and has done so for over 35 years, although it's only been in its current location for the last eight. The entire back wall of the space is devoted to Sir Arthur Conan Doyle, while the sides are filled with paperbacks and hardcovers. The store also has a small publishing arm and a children's section, reportedly very popular.",
+    "description": "Mysterious Bookshop sells new, used, and vintage mysteries and thrillers, and has done so for over 45 years. The entire back wall of the space is devoted to Sir Arthur Conan Doyle, while the sides are filled with paperbacks and hardcovers. The store also has a small publishing arm and a children's section, reportedly very popular.",
     "lat": "40.714924",
     "long": "-74.009211",
     "country": "USA",
     "website": "https://www.mysteriousbookshop.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "The Mysterious Bookshop, in Tribeca, Manhattan, sells new, used, and vintage mysteries and thrillers; it is the oldest mystery book store in America."
   },
   {
     "name": "Bookmarc",
@@ -123,7 +131,8 @@
     "country": "USA",
     "website": "https://www.instagram.com/thebookmarc/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Bookmarc, in the West Village, Manhattan, is owned by the designer Marc Jacobs. It stocks a collection of his stationary and a variety of art books."
   },
   {
     "name": "Ursus Books",
@@ -131,13 +140,14 @@
     "city": "New York",
     "state": "NY",
     "postcode": "10065",
-    "description": "To access Ursus, enter the main lobby of the building (past the doorman) and head back and to the left.",
+    "description": "Ursus Books, on the Upper East Side of Manhattan, is a rare book, map, and print dealer. To access the store, enter the main lobby of the building (past the doorman) and head back and to the left.",
     "lat": "40.775248",
     "long": "-73.962207",
     "country": "USA",
     "website": "https://www.ursusbooks.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Ursus Books, on the Upper East Side of Manhattan, is a new, used, vintage, and rare art reference book, historical map, and decorative print dealer."
   },
   {
     "name": "Alabaster Bookshop",
@@ -145,13 +155,14 @@
     "city": "New York",
     "state": "NY",
     "postcode": "10003",
-    "description": "Situated just around the corner from the Strand bookstore, this small rare bookseller is stuffed to the gills with books. The areas of emphasis include art, fiction, and philosophy (both eastern and western).",
+    "description": "Situated just around the corner from the Strand bookstore, this small used bookseller is stuffed to the gills with books. The areas of emphasis include art, fiction, and philosophy (both eastern and western).",
     "lat": "40.733032",
     "long": "-73.98996",
     "country": "USA",
     "website": "https://www.instagram.com/alabasterbookshop/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Alabaster Bookshop, south of Union Square in Manhattan, is a small used bookshop jammed with books. Areas of emphasis include art, fiction, and philosophy."
   },
   {
     "name": "Unnameable Books",
@@ -165,7 +176,8 @@
     "country": "USA",
     "website": "https://unnameablebooks.square.site/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Unnameable Books, in Prospect Heights, Brooklyn, specializes in new and used poetry and fiction, with a selection of philosophical and left-wing writing."
   },
   {
     "name": "Community Bookstore",
@@ -173,13 +185,14 @@
     "city": "Brooklyn",
     "state": "NY",
     "postcode": "11215",
-    "description": "",
+    "description": "Community Bookstore, in Park Slope, Brooklyn, is a medium-sized general-interest bookstore that claims to be Brooklyn's oldest operating bookstore.",
     "lat": "40.672668",
     "long": "-73.976436",
     "country": "USA",
     "website": "https://www.communitybookstore.net/",
     "events": "",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Community Bookstore, in Park Slope, Brooklyn, is a medium-sized general-interest bookstore that claims to be Brooklyn's oldest operating bookstore."
   },
   {
     "name": "Greenlight Bookstore",
@@ -193,7 +206,8 @@
     "country": "USA",
     "website": "https://www.greenlightbookstore.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Greenlight Bookstore, in Fort Greene, Brooklyn, is a bright, airy store that stocks literary fiction, essays, and non-fiction, and hosts frequent events."
   },
   {
     "name": "Dashwood Books",
@@ -207,7 +221,8 @@
     "country": "USA",
     "website": "https://www.dashwoodbooks.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Dashwood Books, in NoHo, Manhattan, is a small (basement-level, down a flight of stairs) seller of art and photography books that runs its own small press."
   },
   {
     "name": "Molasses Books",
@@ -221,7 +236,8 @@
     "country": "USA",
     "website": "https://www.molassesbooks.org/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": "Molasses Books, in Bushwick, Brooklyn, is a a combination used bookstore, cafe, and bar, selling a selection of fiction, nonfiction, and Brooklyn zines."
   },
   {
     "name": "The Corner Bookstore",
@@ -235,7 +251,8 @@
     "country": "USA",
     "website": "https://cornerbookstorenyc.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "The Corner Bookstore, on the Upper East Side of Manhattan, is a veteran neighborhood bookshop, with a dual emphasis on children's books and adult fiction."
   },
   {
     "name": "East Village Books",
@@ -243,13 +260,14 @@
     "city": "New York",
     "state": "NY",
     "postcode": "10009",
-    "description": "A village institution, East Village Books has remained singularly itself as the rest of the neighborhood has changed around it. Mainly a used-book seller, the store has a selection of dissident literature and other, stranger fare, including copies of the anarchist newspaper The Shadow. Expect the unexpected among it's crowded shelves and low ceiling, and make sure to check the bargain books out back. $30 credit card minimum.",
+    "description": "A village institution, East Village Books has remained singularly itself as the rest of the neighborhood has changed around it. Mainly a used-book seller, the store has a selection of dissident literature and other, stranger fare, including copies of the anarchist newspaper The Shadow. Expect the unexpected among it's crowded shelves and low ceiling, and make sure to check the bargain books out back. Cash only.",
     "lat": "40.727411",
     "long": "-73.984498",
     "country": "USA",
     "website": "https://www.newyorkcitybookbuyer.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "East Village Books, on St. Marks in Manhattan, has withstood the gentrification of the East Village and still buys and sells eclectic used books."
   },
   {
     "name": "Strand Bookstore",
@@ -263,7 +281,8 @@
     "country": "USA",
     "website": "https://www.strandbooks.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Strand Bookstore, near Union Square in Manhattan, is the best-known bookseller in the city, stocking new, used, and rare books on \"18 miles\" of shelves."
   },
   {
     "name": "Bluestockings Cooperative",
@@ -277,7 +296,8 @@
     "country": "USA",
     "website": "https://bluestockings.com/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": "Bluestockings Cooperative Bookstore, in the Bowery, Manhattan, is a community-focused and collectively-run activist center and feminist bookstore and cafe."
   },
   {
     "name": "Kinokunya",
@@ -291,7 +311,8 @@
     "country": "USA",
     "website": "https://usa.kinokuniya.com/stores-kinokuniya-new-york",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": "Kinokunya, in Midtown Manhattan, is a Japanese bookstore and cafe that sells new books in English and Japanese, and has an entire floor devoted to manga."
   },
   {
     "name": "Three Lives & Company",
@@ -305,7 +326,8 @@
     "country": "USA",
     "website": "http://www.threelives.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": "Three Lives & Company, in the West Village, Manhattan, is a gorgeous neighborhood bookstore with knowledgable staff and a selection of literary fiction."
   },
   {
     "name": "Shakespeare & Company",
@@ -313,13 +335,14 @@
     "city": "New York",
     "state": "NY",
     "postcode": "10065",
-    "description": "Sharing a name with the famous Parisian bookshop but no other official ties, this store has a general-interest selection of books on its main level and, downstairs, textbooks for the nearby colleges. The NYU, Gramercy, and Brooklyn locations have all closed in recent years.",
+    "description": "Sharing a name with the famous Parisian bookshop but no other official ties, this store has a general-interest selection of books on its main level and, downstairs, textbooks for the nearby colleges.",
     "lat": "40.768188",
     "long": "-73.963531",
     "country": "USA",
     "website": "https://shop.shakeandco.com/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Book Culture",
@@ -333,7 +356,8 @@
     "country": "USA",
     "website": "https://www.bookculture.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Book Culture on Broadway",
@@ -347,7 +371,8 @@
     "country": "USA",
     "website": "https://www.bookculture.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Book Culture LIC",
@@ -361,7 +386,8 @@
     "country": "USA",
     "website": "https://www.bookculture.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Westsider Rare & Used Books",
@@ -375,7 +401,8 @@
     "country": "USA",
     "website": "http://westsiderbooks.com/bookstore.html",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Word Up Books",
@@ -389,7 +416,8 @@
     "country": "USA",
     "website": "https://www.wordupbooks.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Turn The Page... Again",
@@ -403,7 +431,8 @@
     "country": "USA",
     "website": "http://www.turnthepageagain.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Book Thug Nation",
@@ -417,7 +446,8 @@
     "country": "USA",
     "website": "https://www.instagram.com/bookthugnation/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Posman Books Chelsea Market",
@@ -431,7 +461,8 @@
     "country": "USA",
     "website": "https://www.posmanbooks.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Books Of Wonder",
@@ -445,7 +476,8 @@
     "country": "USA",
     "website": "https://booksofwonder.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Bonnie Slotnick Cookbooks",
@@ -459,7 +491,8 @@
     "country": "USA",
     "website": "http://www.bonnieslotnickcookbooks.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Kitchen Arts & Letters",
@@ -473,7 +506,8 @@
     "country": "USA",
     "website": "https://kitchenartsandletters.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Revolution Books",
@@ -487,7 +521,8 @@
     "country": "USA",
     "website": "https://shop.revolutionbooksnyc.org/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Spoonbill & Sugartown, Booksellers",
@@ -501,7 +536,8 @@
     "country": "USA",
     "website": "https://www.spoonbillbooks.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Melville House Publishers",
@@ -515,7 +551,8 @@
     "country": "USA",
     "website": "https://www.mhpbooks.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Printed Matter",
@@ -529,7 +566,8 @@
     "country": "USA",
     "website": "https://www.printedmatter.org/locations",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "192 Books",
@@ -543,7 +581,8 @@
     "country": "USA",
     "website": "http://www.192books.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Freebird Books",
@@ -557,7 +596,8 @@
     "country": "USA",
     "website": "http://www.freebirdbooks.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Berl's Brooklyn Poetry Shop",
@@ -571,7 +611,8 @@
     "country": "USA",
     "website": "http://www.berlspoetry.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Here's A Book Store",
@@ -585,7 +626,8 @@
     "country": "USA",
     "website": "https://www.facebook.com/profile.php?id=100057614522975",
     "events": "?",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Argosy Books",
@@ -599,7 +641,8 @@
     "country": "USA",
     "website": "https://www.argosybooks.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "POWERHOUSE on 8th",
@@ -613,7 +656,8 @@
     "country": "USA",
     "website": "https://www.powerhousebookstores.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Terrace Books",
@@ -627,7 +671,8 @@
     "country": "USA",
     "website": "https://www.communitybookstore.net/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "BookMark Shoppe",
@@ -641,7 +686,8 @@
     "country": "USA",
     "website": "https://www.bookmarkshoppe.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Better Read Than Dead",
@@ -655,7 +701,8 @@
     "country": "USA",
     "website": "http://betterreadthandeadbooks.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Better Read Than Dead & Burly Coffee",
@@ -669,7 +716,8 @@
     "country": "USA",
     "website": "http://betterreadthandeadbooks.com/",
     "events": "No",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Desert Island Comics",
@@ -683,7 +731,8 @@
     "country": "USA",
     "website": "https://desertislandbrooklyn.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Topos Bookstore Cafe",
@@ -697,7 +746,8 @@
     "country": "USA",
     "website": "https://toposbookstore.com/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Human Relations Books",
@@ -711,7 +761,8 @@
     "country": "USA",
     "website": "http://www.humanrelationsbooks.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Respect For Life Books-N-Things",
@@ -725,7 +776,8 @@
     "country": "USA",
     "website": "https://respectforlifebookstore.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "ETG Book Cafe",
@@ -739,7 +791,8 @@
     "country": "USA",
     "website": "http://www.etgstores.com/bookcafe/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "The Center for Fiction",
@@ -753,7 +806,8 @@
     "country": "USA",
     "website": "https://centerforfiction.org/the-center/bookstore/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Catland",
@@ -767,7 +821,8 @@
     "country": "USA",
     "website": "https://www.catlandbooks.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Logos Bookstore",
@@ -781,7 +836,8 @@
     "country": "USA",
     "website": "https://www.logosbookstorenyc.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Joanne Hendricks Cookbooks",
@@ -795,7 +851,8 @@
     "country": "USA",
     "website": "http://www.joannehendrickscookbooks.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Sister's Uptown Bookstore",
@@ -809,7 +866,8 @@
     "country": "USA",
     "website": "http://www.sistersuptownbookstore.com/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Archestratus",
@@ -823,7 +881,8 @@
     "country": "USA",
     "website": "https://www.archestrat.us/",
     "events": "Yes",
-    "cafe": "Sandwiches and Groceries"
+    "cafe": "Sandwiches and Groceries",
+    "meta": ""
   },
   {
     "name": "Quest Bookshop",
@@ -837,7 +896,8 @@
     "country": "USA",
     "website": "https://www.questbookshop.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "The Austin Book Shop",
@@ -851,7 +911,8 @@
     "country": "USA",
     "website": "https://www.facebook.com/austinbookshop/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "The Book Cellar",
@@ -865,7 +926,8 @@
     "country": "USA",
     "website": "https://www.facebook.com/thebookcellarnyc/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Chartwell Booksellers",
@@ -879,7 +941,8 @@
     "country": "USA",
     "website": "https://www.chartwellbooksellers.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Bookoff",
@@ -893,7 +956,8 @@
     "country": "USA",
     "website": "https://www.bookoffusa.com/bookoff-49-w-45th-ny-store/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "James Cummins Bookseller",
@@ -907,7 +971,8 @@
     "country": "USA",
     "website": "https://www.jamescumminsbookseller.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Books Are Magic (Smith St.)",
@@ -921,7 +986,8 @@
     "country": "USA",
     "website": "https://www.booksaremagic.net/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Books Are Magic (Montague St.)",
@@ -935,7 +1001,8 @@
     "country": "USA",
     "website": "https://www.booksaremagic.net/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Namaste Bookshop",
@@ -949,7 +1016,8 @@
     "country": "USA",
     "website": "https://www.namastebookshop.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Albertine Books",
@@ -963,7 +1031,8 @@
     "country": "USA",
     "website": "https://www.albertine.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Rizzoli Bookstore",
@@ -977,7 +1046,8 @@
     "country": "USA",
     "website": "https://www.rizzolibookstore.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Standards Manual",
@@ -991,7 +1061,8 @@
     "country": "USA",
     "website": "https://standardsmanual.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Westsider Records",
@@ -1005,7 +1076,8 @@
     "country": "USA",
     "website": "http://westsiderbooks.com/recordstore.html",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Kew & Willow Books",
@@ -1019,7 +1091,8 @@
     "country": "USA",
     "website": "https://www.kewandwillow.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Cafe con Libros",
@@ -1033,7 +1106,8 @@
     "country": "USA",
     "website": "https://www.cafeconlibrosbk.com/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "McNally Jackson Books Williamsburg",
@@ -1047,7 +1121,8 @@
     "country": "USA",
     "website": "https://www.mcnallyjackson.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "McNally Jackson Books Seaport",
@@ -1061,7 +1136,8 @@
     "country": "USA",
     "website": "https://www.mcnallyjackson.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "McNally Jackson Books City Point",
@@ -1075,7 +1151,8 @@
     "country": "USA",
     "website": "https://www.mcnallyjackson.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Codex Books",
@@ -1089,7 +1166,8 @@
     "country": "USA",
     "website": "http://codexbooks.info/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "The Lit. Bar",
@@ -1103,7 +1181,8 @@
     "country": "USA",
     "website": "http://www.thelitbar.com/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Shakespeare & Company (Upper West Side)",
@@ -1117,7 +1196,8 @@
     "country": "USA",
     "website": "https://shop.shakeandco.com/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Mil Mundos Books",
@@ -1131,7 +1211,8 @@
     "country": "USA",
     "website": "https://www.milmundosbooks.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Aeon Bookstore",
@@ -1145,7 +1226,8 @@
     "country": "USA",
     "website": "https://www.aeonbookstore.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Bravo's Book Nook",
@@ -1159,7 +1241,8 @@
     "country": "USA",
     "website": "https://www.bravosbooknook.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Karma Bookstore",
@@ -1173,7 +1256,8 @@
     "country": "USA",
     "website": "https://bookstore.karmakarma.org/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Cups and Books",
@@ -1187,7 +1271,8 @@
     "country": "USA",
     "website": "https://www.facebook.com/cupsandbooksllc/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Book Club Bar",
@@ -1201,7 +1286,8 @@
     "country": "USA",
     "website": "https://www.bookclubbar.com/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Pillow-Cat Books",
@@ -1215,7 +1301,8 @@
     "country": "USA",
     "website": "https://www.pillowcatbooks.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Sweet Pickle Books",
@@ -1229,7 +1316,8 @@
     "country": "USA",
     "website": "https://www.sweetpicklebooks.com/",
     "events": "Yes",
-    "cafe": "No, but they'll give you pickles in exchange for used books"
+    "cafe": "No, but they'll give you pickles in exchange for used books",
+    "meta": ""
   },
   {
     "name": "Yu and Me Books",
@@ -1243,7 +1331,8 @@
     "country": "USA",
     "website": "https://www.yuandmebooks.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Bookoff Brooklyn",
@@ -1257,7 +1346,8 @@
     "country": "USA",
     "website": "https://www.bookoffusa.com/brooklyn/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Troubled Sleep Books",
@@ -1271,7 +1361,8 @@
     "country": "USA",
     "website": "https://www.instagram.com/troubledsleepbooks/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Leaves Bookstore",
@@ -1285,7 +1376,8 @@
     "country": "USA",
     "website": "https://www.leavesbookstore.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Burnt Books",
@@ -1299,7 +1391,8 @@
     "country": "USA",
     "website": "https://www.instagram.com/burnt_books_/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "The Drama Book Shop",
@@ -1313,7 +1406,8 @@
     "country": "USA",
     "website": "https://www.dramabookshop.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Recirculation",
@@ -1327,7 +1421,8 @@
     "country": "USA",
     "website": "https://www.instagram.com/recirculation.nyc/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "McNally Jackson Rockefeller Center",
@@ -1341,7 +1436,8 @@
     "country": "USA",
     "website": "https://www.mcnallyjackson.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "The Strand At Columbus Ave",
@@ -1355,7 +1451,8 @@
     "country": "USA",
     "website": "https://www.strandbooks.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Dear Friend Books",
@@ -1369,7 +1466,8 @@
     "country": "USA",
     "website": "https://www.dearfriendbooks.com/",
     "events": "No",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "P&T Knitwear",
@@ -1383,7 +1481,8 @@
     "country": "USA",
     "website": "https://www.ptknitwear.com/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Adanne",
@@ -1397,7 +1496,8 @@
     "country": "USA",
     "website": "https://adanne.co/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "POWERHOUSE @ IC",
@@ -1411,7 +1511,8 @@
     "country": "USA",
     "website": "https://www.powerhousebookstores.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Quimby's Bookstore",
@@ -1425,7 +1526,8 @@
     "country": "USA",
     "website": "https://quimbysnyc.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "The Word Is Change",
@@ -1439,7 +1541,8 @@
     "country": "USA",
     "website": "https://www.thewordischange.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Left Bank Books",
@@ -1453,7 +1556,8 @@
     "country": "USA",
     "website": "https://www.leftbankbooksny.com/",
     "events": "No",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "1804 Books",
@@ -1467,7 +1571,8 @@
     "country": "USA",
     "website": "https://1804books.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Black Spring Books",
@@ -1481,7 +1586,8 @@
     "country": "USA",
     "website": "https://www.blackspringbookstore.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Passageway Books",
@@ -1495,7 +1601,8 @@
     "country": "USA",
     "website": "https://www.instagram.com/passageway_books/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Taylor & Co. Books",
@@ -1509,7 +1616,8 @@
     "country": "USA",
     "website": "https://www.taylorcobooks.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "The Ripped Bodice",
@@ -1523,7 +1631,8 @@
     "country": "USA",
     "website": "https://www.therippedbodicela.com/ripped-bodice-brooklyn",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Lofty Pigeon Books",
@@ -1537,7 +1646,8 @@
     "country": "USA",
     "website": "https://www.loftypigeonbooks.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Village Works",
@@ -1551,7 +1661,8 @@
     "country": "USA",
     "website": "https://www.villageworksnyc.com/",
     "events": "Yes",
-    "cafe": "Soon?"
+    "cafe": "Soon?",
+    "meta": ""
   },
   {
     "name": "Topos Too",
@@ -1565,7 +1676,8 @@
     "country": "USA",
     "website": "https://www.toposbookstore.com/",
     "events": "?",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "The World's Borough Bookshop",
@@ -1579,7 +1691,8 @@
     "country": "USA",
     "website": "https://www.theworldsboroughbookshop.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Bibliotheque",
@@ -1593,7 +1706,8 @@
     "country": "USA",
     "website": "https://www.bibliothequenyc.com/",
     "events": "No",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Shakespeare & Company (Manhattan Valley/Columbia University)",
@@ -1607,7 +1721,8 @@
     "country": "USA",
     "website": "https://shop.shakeandco.com/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Liz's Book Bar",
@@ -1621,7 +1736,8 @@
     "country": "USA",
     "website": "https://www.lizsbookbar.com/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Honey Moon Coffee Shop",
@@ -1635,7 +1751,8 @@
     "country": "USA",
     "website": "https://honeymooncoffee.shop/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "Sullaluna Bistrot & Bookshop",
@@ -1649,7 +1766,8 @@
     "country": "USA",
     "website": "https://www.instagram.com/sullaluna.nyc/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   },
   {
     "name": "The Nonbinarian Bookstore",
@@ -1663,7 +1781,8 @@
     "country": "USA",
     "website": "https://thenonbinarian.gay/",
     "events": "Yes",
-    "cafe": "No"
+    "cafe": "No",
+    "meta": ""
   },
   {
     "name": "Hive Mind Books",
@@ -1677,6 +1796,7 @@
     "country": "USA",
     "website": "https://www.hivemindbooks.com/",
     "events": "Yes",
-    "cafe": "Yes"
+    "cafe": "Yes",
+    "meta": ""
   }
 ]