You will build: A product list read from your own Postgres database, with a search box that filters it as you type
Read first: Show data from an API
In this tutorial you connect a Postgres database, such as one on Neon or Supabase, write a SQL query with a parameter, and feed that parameter from a search box so the list filters as the visitor types. You need a Postgres database you can reach from the internet and a user with read access.
Prepare a table
Create sample data
If you do not have a table to show yet, open the SQL editor of your database provider and run:
sqlcreate table products (id serial primary key, name text not null, price numeric(8, 2) not null); insert into products (name, price) values ('Canvas tote', 24.00), ('Ceramic mug', 14.50), ('Linen apron', 32.00), ('Notebook', 9.90), ('Oak coaster set', 18.00), ('Wool blanket', 89.00);Find the connection details
In your provider's dashboard, open the connection details of the database (in Neon and Supabase, press Connect on the project). Copy the host, port, database name, user and password. They are the parts of a connection string like
postgresql://user:password@host:5432/database.
Connect the database
Add a PostgreSQL integration
Open the Data workspace from the bottom of the left sidebar. Next to Integrations, press + and choose PostgreSQL. Name it
Shop database.Fill in the connection
In the Connection card, enter the Host (for example
ep-cool-name.us-east-2.aws.neon.tech), the Port (usually5432), the Database and the User. Keep Ssl onrequire, or pickverify-fullto also check the server certificate.Add the password
In the Secrets card, enter the Password of the database user. It is encrypted on the server and never shown again.
Create and test
Press Create integration, then Run test in the Test connection card. Connected means Malla reached the database and ran a simple query. An error shows the message and a code, such as a wrong password or a host that does not answer.
The Shop database integration is listed under Integrations, and its test says Connected.
Query the table
Look at the tables
Next to Queries, press + and rename the query to
products. In Source, set Integration toShop databaseand Operation to List tables, then press Run in the Result card. You see every table the user can read, with its columns.Write the SQL
Set Operation to Query. In Sql, write:
sqlselect id, name, price from products where name ilike '%' || $1 || '%' order by name$1is a placeholder. Its value comes from Params, never from the SQL text, so a visitor cannot inject SQL through it.Give the parameter a value
Under Params, press Add item and type
"mug", with the quotes: each item takes a JSON value, so text needs quotes and numbers do not. Max rows returns 200 rows when you leave it empty, and at most 1000.Return the rows
The query returns an object with
rows,rowCount,columnsandtruncated. In When it runs, set Response path torowsso the query returns only the list. Press Run: the result is one product, the ceramic mug.
Add a live search
Create a search variable
Next to Page variables, press + and choose String. Rename it to
searchand leave the default value empty.Feed the parameter from the variable
Select the
productsquery. Next to the"mug"item under Params, press Use an expression (the ƒ button) and replace the value withvars.search.In When it runs, pick Client. The query now runs in the browser on load and again whenever
vars.searchchanges. Debounce (ms) waits until the visitor stops typing; the default is 250 ms. The browser asks Malla to run the query, so the password never leaves the server.Add the search box
Back on the canvas, press + in the Layers tab and choose Input. In the Field section, set Placeholder to
Search productsand set Value tosearch. Typing in the box now writes to the variable.List the products
Insert a Collection list under the search box. In Collection list, set Source to Expression and Items to
queries.products.data. Add two texts inside Item and bind them toitem.nameanditem.pricein Typography. Set Empty text toNo products match your search.
The canvas lists all six products, because the search is empty.
Try the search
Press ⌘↵ to preview the page and type
oain the search box. After a short pause the list shows only the coaster set. Typexyzto see the empty text. Press ⌘↵ again to go back to editing.Publish
Press Publish and open the staging page. The search works the same way for your visitors.
Your page reads products from your own database and filters them as visitors type.
What you learned
- A PostgreSQL integration stores the host, database and user, and keeps the password encrypted on the server.
$1,$2placeholders take their values from Params, and a parameter can read a variable.- A client query refetches when the variables it reads change, which turns an input into a live search.
Read the guides behind this tutorial: