Deploy a directory site

A browsable, searchable directory on the managed database. Live with sample data the moment it deploys, then yours after one import.

The directory-starter template is a directory site: a list people can browse by category and search, with a page for each entry. It ships with about 50 AI and developer tools as sample data, so it is a live site from the first deploy. You swap in your own data when you are ready.

Open the deploy link and sign in if asked. To change the code later, click Use this template on GitHub first and deploy your own copy instead.

2. Add the managed database

On the deploy form, check Add a managed database. Dockhold injects DATABASE_URL, and the app creates its table and fills it with the sample entries on first boot. It runs on the free plan.

3. Deploy

Click Deploy. The site goes live at its dockhold.app address, already filled in. The data lives in the database, so it stays across restarts and deploys. A deploy never seeds twice or wipes what you loaded: the sample data goes in only when the table is empty.

4. Load your own data

Your own entries go in with a one-time database import, with no new deploy. Importing needs a paid plan.

Save your data as a CSV with the header row name,tagline,description,url,category,pricing,tags. Only name is required, and tags are separated by |. Data in another database works the same way: export it to a CSV with these columns. In your copy of the template, run node scripts/csv-to-dump.js your-data.csv > my-directory.sql. The file adds new rows and updates matching ones, so it can go in over the sample data. To keep only your own entries, add TRUNCATE entries; as its first line.

A database takes one import, so put all your entries in that one file.

Then open the app's Data tab, upload the file under Import an existing database, and wait until it shows as done. The import applies all of it or nothing. Refresh your site and your entries are there.

How it works

  • / lists the entries; ?q= searches and ?category= filters. /e/<slug> is one entry's page and /api/entries returns them all as JSON.
  • Visitors can only read. There is no form to post to, so you change the data by importing.
  • Every query is parameterized and every value is escaped before it is shown, so imported text cannot add markup to a page.
  • On a first deploy the database may still be starting, so the app retries the connection a few times instead of crashing.

The full reference is in the template's README.

Next

Suggested guides
↑↓ to move ↵ to open Esc to close From the Dockhold docs