Notion’s contains() formula checks if one text string appears inside another. By default, this function performs a case-sensitive match, meaning it treats uppercase and lowercase letters as different characters. This behavior can cause false negatives when you need to compare text regardless of capitalization, such as matching user input, imported data, or mixed-case tags. This article explains how to modify the contains() formula to perform a case-insensitive match using the lower() function.
Key Takeaways: Case-Insensitive Match in Notion Formulas
- lower() wrapped around both arguments: Convert both the source text and the search term to lowercase before using contains()
- contains(lower(prop(“Name”)), lower(“search”)): The exact formula syntax for a case-insensitive match
- Test with mixed-case data: Verify the formula returns true for strings like “Hello”, “HELLO”, and “hElLo”
Why the Default contains() Is Case-Sensitive
The contains() function in Notion compares text character by character using the exact Unicode code point. Because uppercase letters have different code points than their lowercase counterparts, contains("Hello", "hello") returns false. This is standard behavior in many programming languages and formula systems. Notion does not provide a built-in contains() variant that ignores case, so you must transform both strings to the same case before comparison.
The lower() function converts any text to all lowercase characters. When you wrap both the source property and the search term with lower(), the contains() function compares two lowercase strings. This effectively removes case as a factor in the match. The same technique works with upper() if you prefer uppercase conversion, but lower() is more common and readable.
Steps to Build a Case-Insensitive contains() Formula
- Open the formula editor
Add a Formula property to your database. Click on any cell in that property column, then click Edit property and then Edit formula. - Reference the source property with lower()
Typelower(prop("YourPropertyName")). ReplaceYourPropertyNamewith the exact name of the text property you want to search. This converts the source text to lowercase. - Wrap the search term with lower()
After the comma insidecontains(), typelower("search term"). Replacesearch termwith the text you want to find. For example:lower("urgent"). - Combine everything into the final formula
Write:contains(lower(prop("Name")), lower("urgent")). This formula returnstrueif the Name property contains the word “urgent” in any capitalization. - Test with various capitalizations
Create a few test rows with values like “URGENT”, “Urgent”, “urgent”, and “uRgEnT”. The formula should returntruefor all of them.
Using a Dynamic Search Term from Another Property
Instead of hardcoding the search term as a string, you can reference another property. For example, if you have a property called “Search Term” where users can type any text, use this formula:
contains(lower(prop("Name")), lower(prop("Search Term")))
This makes the search dynamic. Any text entered in the Search Term property will be matched case-insensitively against the Name property. Note that if the Search Term property is empty, the formula returns false because lower("") produces an empty string and contains() with an empty search string returns false in Notion.
Common Issues with Case-Insensitive contains()
Formula Returns False for Partially Matching Text
If your formula returns false when you expect true, check for leading or trailing spaces in the property values. For example, " Hello" contains a leading space. Use the replaceAll() function to strip spaces: contains(lower(replaceAll(prop("Name"), " ", "")), lower("hello")). This removes all spaces before converting to lowercase.
Formula Breaks When Property Contains Numbers or Symbols
The lower() function only affects letters. Numbers and symbols like @, #, or % pass through unchanged. This is not a bug. The formula will still match correctly because contains() compares the full string including those characters. If you need to ignore punctuation, wrap the property with replaceAll() to remove non-alphanumeric characters before applying lower().
Formula Does Not Work Inside a Rollup or Lookup
When using contains() inside a Rollup or Lookup formula, you must first convert the rolled-up value to text using format(). For example: contains(lower(format(prop("RollupProperty"))), lower("test")). Without format(), the Rollup value may be interpreted as a number or date, causing the formula to fail.
| Item | Case-Sensitive contains() | Case-Insensitive contains() |
|---|---|---|
| Formula syntax | contains(prop("Name"), "hello") |
contains(lower(prop("Name")), lower("hello")) |
| Match “Hello” | false | true |
| Match “HELLO” | false | true |
| Match “hello” | true | true |
| Performance | Faster (single function call) | Slower (three function calls) |
You can now build Notion formulas that match text regardless of capitalization. Use lower() on both the source property and the search term to create a reliable case-insensitive contains(). For advanced filtering, combine this technique with the if() function to return custom labels like “Match Found” or “No Match”. Remember to test with edge cases such as empty strings, special characters, and rolled-up values to ensure your formula behaves as expected.