The Best Way to Create Recurring Tasks in Notion (2024)

Our work is reader-supported; if you buy through our links, we may earn an affiliate commission.

Play Video

This tutorial will show you the exact, step-by-step process to create recurring tasks in Notion and completely automate them.

That means you’ll be able to check off a task, and everything else simply happens for you – the due date gets moved, the Done checkbox becomes un-checked (and/or Status gets set back to To Do), and the task is ready and waiting for you the next time you need to do it.

Yes, seriously.

The method I’ll show you in this article requires no coding and can be done for free. Additionally, once you’ve completed the initial setup, you’re good to go – your recurring tasks will just work.

Here’s a breakdown of what we’ll be doing:

  1. Set up recurring tasks inside of Notion
  2. Automate those recurring tasks using Pipedream (free)

The automation here is driven by the Notion API, and by some code that I’ve written for you.

All in all, this automation should take you no more than 10 minutes to set up. Let’s go!

Before you can automate your recurring tasks, you’ll need to set up a system to add recur settings to those tasks in the first place – e.g. “Every other day”, or “Every 2 months”.

Fortunately, we’ve done this work for you. My team and I have added a set of powerful recurring task features to Ultimate Tasks, my free task manager template.

Ultimate Tasks template for Notion

Ultimate Tasks lets you manage your tasks and projects entirely inside Notion. With it, you can:

  • Create and manage projects
  • Create sub-tasks
  • View your tasks in date-based Smart Lists (Today, Next 7 Days, etc)

You can get Ultimate Tasks for free and join my Notion Tips newsletter below – once you sign up, I’ll also send you all of my other free Notion templates, along with other cheat sheets and resources.

Join the Notion Tips newsletter and get this template for free:

If you’d like to go further and turn Notion into a complete productivity system, check out Ultimate Brain – my all-in-one second brain system for Notion.

Ultimate Brain uses the same task management set up as Ultimate Tasks, and also adds note-taking, goal tracking, optional GTD tools, a journal, recipe tracker, book tracker, and much more:

Recommended
Ultimate Brain: The Complete Second Brain for Notion

Want to turn Notion into a complete productivity system? Ultimate Brain includes all the features from Ultimate Tasks - and combines them with notes, goals, and advanced project management features.

Learn More

For the rest of this tutorial, I’ll assume you’re using either Ultimate Tasks or Ultimate Brain. The setup process is exactly the same for both, and each template comes with all of the required recurring task properties built-in.

If you want to implement the recurring tasks features shown into your own template, you can see all of them in my Advanced Recurring Task Dates template. This template exists as an educational proof-of-concept, so it’s less useful as an actual task manager.

To set up a recur interval for a task, open the task as a page. You’ll see a Due Date property, as well as three properties for setting up a recurring task:

Recur Settings

These give you all the tools you need to set almost any recur interval you could want.

  • Recur Interval – A simple number property that works with Recur Unit.
  • Recur Unit – The available recur units, including
    • Day(s)
    • Week(s)
    • Month(s)
    • Month(s) on the Last Day
    • Month(s) on the Last Weekday
    • Month(s) on the First Weekday
    • Year(s)
  • Days (Only if Set to 1 Day(s)) – this will let you set a task to recur on specific days on the week – e.g. Mon/Wed/Fri
    • Recur Unit must be set to Day(s) and Recur Interval must be set to 1.

Once you set up a recur interval, you’ll also see a property called Next Due. This shows the next due date for the recurring task.

Here are a few examples of recur intervals you could set up using these three properties:

Due Every Day:

  • Recur Interval : 1
  • Recur Unit: Day(s)
Daily recurring task example

Due Every 2 Months on the Last Weekday

  • Recur Interval: 2
  • Recur Unit: Month(s) on the Last Weekday
Every two months on the last weekday example

Due Every Tuesday and Thursday

  • Recur Interval: 1
  • Recur Unit: Day(s)
  • Days (Only if Set to 1 Day(s)): Tuesday, Thursday
Every Tuesday and Thursday example

As you can see, there are many combinations of these three properties that will let you create most of the useful recur intervals that you could create in other apps like Todoist, Asana, or ClickUp.

You can “complete” a recurring task directly inside of Notion simply by changing the Due Date property to the date displayed in the Next Due property after you finish the task.

Note that you do not need to click the Done checkbox property in this case, as it won’t do anything. Likewise, if you use a Status property for tracking tasks, you won’t need to change it either.

If you want to be able to click Done, or change a Status property to Done, and have the task automatically update its Due Date, then continue on to the next portion of the tutorial.

Using the Notion API, we can automate all sorts of processes inside of Notion that used to be done manually. This includes processing recurring tasks!

If you’re curious about the details, I’ve written about them in the two toggle sections below. Feel free to read those; otherwise, you can skip them and get right to building.

Essentially, an app can have an API (Application Programming Interface) that allows outsiders – including indie developers and even other apps – to work with certain pieces of its code.

Here’s an example of an API in action. In Slack, I can use the Giphy extension – which leverages the Giphy API – to paste a gif right in one of my conversations.

There are several tools – we can call them integration builders – that let you connect different app APIs together. Some focus on providing a set of no-code tools, allowing you to build automations without coding at all.

These include Zapier, IFTTT, Make.com, and others.

Others are code-light; they provide some no-code tools, but also allow you to write your own code – without having to worry about things like authentication, security, and server infrastructure.

Pipedream is one of those tools, and it’s the one I personally use to build all my automations – and to build automations that I can share with you in these tutorials.

If you’re curious, here’s how the automation of recurring tasks works – both in Notion an in basically any productivity app.

When you set up a recurring task and set it to “Done”, here’s what happens from the app’s perspective:

  • The user has set the task to “Done”, so run the recurring tasks script
  • Update the Due Date as specified by the user’s recur interval (e.g. “every other day”)
  • Uncheck the “Done” box

There’s another way an app could handle recurring tasks: Instead of editing the task you checked off, it could create a duplicate of that task with the new due date. However, most productivity apps use the method I’ve just described instead.

My Ultimate Tasks template contains all the logic needed to calculate the Next Due Date right within the template itself. This is very useful – it allows you to use the manual method of updating recurring tasks if you want, but it also saves us the trouble of adding very complex date calculation code to our automation.

Here’s all that our automation will be doing.

  • Step 1: Search through your tasks database in Notion, looking for tasks that have been marked Done and that have a date displayed in the Next Due property.
  • Step 2: For each found task that fits those two criteria, update the Due Date property to have the date displayed in the Next Due property, and then un-check the Done checkbox property.

That’s it!

Note: The newest version of this automation, linked below, can process tasks that use either a Checkbox property or a Status property for tracking task status.

In the next section of the guide, I’ll walk you through the exact steps to setting up your automated recurring tasks workflow.

Now that your tasks database in Notion is all set up, all that’s left to do is create that automation that will actually process your completed recurring tasks.

I’ve built this workflow for you in Pipedream, an automation builder that allows developers to build and share workflows with others.

Since Pipedream allows me to use code to build workflows, I’m able to build truly custom tools that fit the exact needs of Notion users. (This is why I don’t use other tools, such as Zapier or Make).

To get started, click the link below to instantly import my recurring tasks workflow into your Pipedream account. If you don’t already have an account, you’ll be prompted to create one. And yes, it’s free!

Essential
Notion – Automated Recurring Tasks

This workflow adds completely automated recurring tasks to Notion.

Use This Workflow
This workflow is 100% free to use, and this link adds extra perks over the normal free Pipedream account. However, I'll earn a commission if you click this link and upgrade to a paid Pipedream account (at no extra cost to you).

Full disclosure: I’m both a heavy Pipedream user and an affiliate. If you use my link and decide to upgrade to a paid plan, I’ll earn a commission (and if you do, thank you! It helps support my work).

That said, Pipedream has a very generous free plan. You can do a lot more with their free plan than you can with the free plans of other automation builders.

And when you use my link, your Free plan gets even better. Normally, Pipedream‘s free plan limits you to 3 connected apps – but my link raises that limit to 5 connected apps, allowing you to build even more automations before needing to upgrade.

Once you’ve added the workflow to your account, follow the instructions in this brief video to get it all set up. That’s it!

If you encounter a bug or issue, you can report it at the Github repo I’ve set up for this automation.

I’m able to ship new versions of the notion_recurring_tasks step in this workflow when I fix bugs and add improvements.

These new versions won’t automatically apply to your copy of the workflow, but you can easily update your workflow to use them with just a click.

To check for new updates, first find your workflow in Pipedream and hit the Edit button.

Screenshot showing the Edit button for the workflow.

Once you’re in the workflow editor, refresh the page. You need to do this in order to see the Update button.

Afterwards, you should see a red Update button on the notion_recurring_tasks action if there’s an update available.

Screenshot showing the Update button in the Pipedream workflow builder.

Depending on the nature of the update, you may need to set your property options again. I recommend testing the workflow after updating as well.

In this section, I’ve built out a few toggle blocks that contain additional information you can use to customize the way recurring tasks work in your own Notion workspace.

If you want to build your own Notion systems with our recurring tasks properties, this section is for you. Below, I’ve included all of the formulas from our Advanced Recurring Task Dates template.

This is a stripped-down template that only includes the properties needed for processing recurring tasks – you’ll find these exact same properties in Ultimate Brain and Ultimate Tasks, which are functional, ready-to-use templates.

A couple of things to keep in mind:

  • My team and I generally cannot provide free support for these formulas. If you’re an Ultimate Brain customer, however, you can get support in our customer community.
  • You may use the formulas below for personal or internal Notion systems, but they may not be used in distributed Notion templates (free or paid), products, or consulting packages without permission. Please reach out to inquire about using these formulas for one of these use cases.

This system uses the following non-Formula properties:

Property NameProperty TypeProperty Options
DueDateN/A
Recur IntervalNumberN/A
Recur UnitSelectDays(s), Week(s), Month(s), Month(s) on the Last Day, Month(s) on the First Weekday, Month(s) on the Last Weekday, Year(s),
Days (Only if Set to 1 Day(s))Multi-SelectMonday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday

See the toggle selection below this one for information on translating property options into another language.

In addition, five formula properties are required: UTC Offset, Type, Localization Key, Next Due, and Next Due API. These properties should be created in that listed order, and the non-formula properties must be created first with the correct names.

Here’s the code for each formula for reference.

UTC Offset

This property helps Pipedream process recurring tasks using your local timezone. Without it, the Notion API sees all date/time values from Formula-type properties in UTC time, which can cause problems.

As long as you set your timezone correctly in the Trigger step of the Pipedream automation, this value will be automatically set to the correct value when the Pipedream automation runs. It will match your locale’s UTC offset (for example, Denver’s current offset is -6, for MDT time. Outside of Daylight Savings Time, it is -7. This semi-annual change is why letting Pipedream set your offset automatically is a good idea.

0
Code language: JavaScript (javascript)

Localization Key

This formula will allow you to translate the options in Recur Unit and Days (Only if Set to 1 Day(s)) into your own language. If you change them in those properties, make the matching changes here. This formula ensures that the Next Due formula uses their position in the list, rather than the names directly – hence allowing for translation.

[
/* Rewrite these weekday and recur unit options in your own language, so your second brain can work even better with your first. Make sure to set up the same options in the "Recur Unit" and "Days (Only If Set to 1 Day(s))" properties afterward, so you can select them. Feel free to remove the original names afterward! */

/* ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] */
["lunes", "3ª", "mercredi", "木曜日", "piątek", "lørdag", "Double Sunday"],

/* ["Day(s)", "Week(s)", "Month(s)", "Year(s)", "Month(s) on the Last Day", "Month(s) on the First Weekday", "Month(s) on the Last Weekday"] */
["Day(s)", "Week(s)", "Month(s)", "Year(s)", "Month(s) on the Last Day", "Month(s) on the First Weekday", "Month(s) on the Last Weekday"]
]
Code language: JavaScript (javascript)

Next Due

This is the formula that actually calculates your task’s next due date. It takes many piece of data into account, including the task’s Due date, the current date (in the case of overdue tasks), Recur Unit/Interval, etc.

if(!empty(prop("Recur Interval")) and !empty(prop("Due")),
    if(prop("Recur Interval") > 0 and prop("Recur Interval") == ceil(prop("Recur Interval")),
        lets(
            debug, false,
            
            recurUnit, ifs(
                or(prop("Recur Unit") == at(at(prop("Localization Key"), 1), 0), prop("Recur Unit") == "Day(s)"), "days",
                or(prop("Recur Unit") == at(at(prop("Localization Key"), 1), 1), prop("Recur Unit") == "Week(s)"), "weeks",
                or(prop("Recur Unit") == at(at(prop("Localization Key"), 1), 2), prop("Recur Unit") == "Month(s)"), "months",
                or(prop("Recur Unit") == at(at(prop("Localization Key"), 1), 3), prop("Recur Unit") == "Year(s)"), "years",
                or(prop("Recur Unit") == at(at(prop("Localization Key"), 1), 4), prop("Recur Unit") == "Month(s) on the Last Day"), "monthsonthelastday",
                or(prop("Recur Unit") == at(at(prop("Localization Key"), 1), 5), prop("Recur Unit") == "Month(s) on the First Weekday"), "monthsonthefirstweekday",
                or(prop("Recur Unit") == at(at(prop("Localization Key"), 1), 6), prop("Recur Unit") == "Month(s) on the Last Weekday"), "monthsonthelastweekday",
                "days"
            ),
            
            weekdays, match([
                if(
                    or(includes(prop("Days (Only if Set to 1 Day(s))"), at(at(prop("Localization Key"), 0), 1 - 1)), includes(prop("Days (Only if Set to 1 Day(s))"), "Monday")), 1, false
                ),
                
                if(
                    or(includes(prop("Days (Only if Set to 1 Day(s))"), at(at(prop("Localization Key"), 0), 2 - 1)), includes(prop("Days (Only if Set to 1 Day(s))"), "Tuesday")), 2, false
                ),
                
                if(
                    or(includes(prop("Days (Only if Set to 1 Day(s))"), at(at(prop("Localization Key"), 0), 3 - 1)), includes(prop("Days (Only if Set to 1 Day(s))"), "Wednesday")), 3, false
                ),
                
                if(
                    or(includes(prop("Days (Only if Set to 1 Day(s))"), at(at(prop("Localization Key"), 0), 4 - 1)), includes(prop("Days (Only if Set to 1 Day(s))"), "Thursday")), 4, false
                ),
                
                if(
                    or(includes(prop("Days (Only if Set to 1 Day(s))"), at(at(prop("Localization Key"), 0), 5 - 1)), includes(prop("Days (Only if Set to 1 Day(s))"), "Friday")), 5, false
                ),
                
                if(
                    or(includes(prop("Days (Only if Set to 1 Day(s))"), at(at(prop("Localization Key"), 0), 6 - 1)), includes(prop("Days (Only if Set to 1 Day(s))"), "Saturday")), 6, false
                ),
                
                if(
                    or(includes(prop("Days (Only if Set to 1 Day(s))"), at(at(prop("Localization Key"), 0), 7 - 1)), includes(prop("Days (Only if Set to 1 Day(s))"), "Sunday")), 7, false
                )
            ], "[1-7]"),
            
            dateDue, parseDate(formatDate(prop("Due"), "YYYY-MM-DD")),
            
            dateDueEnd, parseDate(formatDate(dateEnd(prop("Due")), "YYYY-MM-DD")),
            
            timeNow, now(),
            
            offsetTimeNow, dateAdd(timeNow, prop("UTC Offset"), "hours"),

            inUTC, if(formatDate(now(), "ZZ") == "+0000", true, false),
            
            hasValidOffset, if(!empty(prop("UTC Offset")) and prop("UTC Offset") >= -12 and prop("UTC Offset") <= 14, true, false),
            
            hasRange, dateEnd(dateDueEnd) > dateStart(dateDue),
            
            dueRange, dateBetween(dateDueEnd, dateDue, "days"),
            
            conditionalTimeNow, if(inUTC and hasValidOffset, offsetTimeNow, timeNow),
            
            conditionalDateNow, parseDate(formatDate(conditionalTimeNow, "YYYY-MM-DD")),
            
            recurUnitLapseLength, if(includes(["days", "weeks", "months", "years"], recurUnit), dateBetween(conditionalDateNow, dateDue, recurUnit) / prop("Recur Interval"), false),
            
            lastDayBaseDate, if(
                includes(["monthsonthelastday", "monthsonthefirstweekday", "monthsonthelastweekday"], recurUnit),
                if(year(conditionalDateNow) * 12 + month(conditionalDateNow) - (year(dateDue) * 12 + month(dateDue)) > 0,
                    dateSubtract(dateAdd(dateSubtract(dateAdd(dateDue, ceil((year(conditionalDateNow) * 12 + month(conditionalDateNow) - (year(dateDue) * 12 + month(dateDue))) / prop("Recur Interval")) * prop("Recur Interval"), "months"), date(dateAdd(dateDue, ceil((year(conditionalDateNow) * 12 + month(conditionalDateNow) - (year(dateDue) * 12 + month(dateDue))) / prop("Recur Interval")) * prop("Recur Interval"), "months")) - 1, "days"), 1, "months"), 1, "days"),
                    dateSubtract(dateAdd(dateSubtract(dateAdd(dateDue, prop("Recur Interval"), "months"), date(dateAdd(dateDue, prop("Recur Interval"), "months")) - 1, "days"), 1, "months"), 1, "days")),
                false
            ),
            
            firstDayBaseDate, if(lastDayBaseDate != false, dateSubtract(lastDayBaseDate, date(lastDayBaseDate) - 1, "days"), false),
            
            firstWeekdayBaseDate, if(lastDayBaseDate != false,
                if(
                    test(day(firstDayBaseDate), "6|7"), 
                    dateAdd(firstDayBaseDate, 8 - day(firstDayBaseDate), "days"),
                    firstDayBaseDate
                ),
                false
            ),
            
            lastWeekdayBaseDate, if(lastDayBaseDate != false,
                if(
                    test(day(lastDayBaseDate), "6|7"), 
                    dateSubtract(lastDayBaseDate, day(lastDayBaseDate) - 5, "days"),
                    lastDayBaseDate
                ),
                false
            ),
            
            nextLastBaseDate, if(lastDayBaseDate != false,
                dateSubtract(dateAdd(dateSubtract(dateAdd(lastDayBaseDate, prop("Recur Interval"), "months"), date(dateAdd(lastDayBaseDate, prop("Recur Interval"), "months")) - 1, "days"), 1, "months"), 1, "days"),
                false
            ),
            
            nextFirstBaseDate, if(lastDayBaseDate != false, dateSubtract(nextLastBaseDate, date(nextLastBaseDate) - 1, "days"), false),
            
            nextFirstWeekday, if(lastDayBaseDate != false,
                if(
                    test(day(nextFirstBaseDate), "6|7"), 
                    dateAdd(nextFirstBaseDate, 8 - day(nextFirstBaseDate), "days"),
                    nextFirstBaseDate
                ),
                false
            ),
            
            nextLastWeekday, if(lastDayBaseDate != false,
                if(
                    test(day(nextLastBaseDate), "6|7"), 
                    dateSubtract(nextLastBaseDate, day(nextLastBaseDate) - 5, "days"),
                    nextLastBaseDate
                ),
                false
            ),
            
            nextDueStart, ifs(
                recurUnit == "days" and length(weekdays) > 0 and prop("Recur Interval") == 1, 
                    if(conditionalDateNow >= dateDue,
                        ifs(
                            includes(weekdays, format(day(dateAdd(conditionalDateNow, 1, "days")))), dateAdd(conditionalDateNow, 1, "days"),
                            includes(weekdays, format(day(dateAdd(conditionalDateNow, 2, "days")))), dateAdd(conditionalDateNow, 2, "days"),
                            includes(weekdays, format(day(dateAdd(conditionalDateNow, 3, "days")))), dateAdd(conditionalDateNow, 3, "days"),
                            includes(weekdays, format(day(dateAdd(conditionalDateNow, 4, "days")))), dateAdd(conditionalDateNow, 4, "days"),
                            includes(weekdays, format(day(dateAdd(conditionalDateNow, 5, "days")))), dateAdd(conditionalDateNow, 5, "days"),
                            includes(weekdays, format(day(dateAdd(conditionalDateNow, 6, "days")))), dateAdd(conditionalDateNow, 6, "days"),
                            includes(weekdays, format(day(dateAdd(conditionalDateNow, 7, "days")))), dateAdd(conditionalDateNow, 7, "days"),
                            false
                        ),
                        ifs(
                            includes(weekdays, format(day(dateAdd(dateDue, 1, "days")))), dateAdd(dateDue, 1, "days"),
                            includes(weekdays, format(day(dateAdd(dateDue, 2, "days")))), dateAdd(dateDue, 2, "days"),
                            includes(weekdays, format(day(dateAdd(dateDue, 3, "days")))), dateAdd(dateDue, 3, "days"),
                            includes(weekdays, format(day(dateAdd(dateDue, 4, "days")))), dateAdd(dateDue, 4, "days"),
                            includes(weekdays, format(day(dateAdd(dateDue, 5, "days")))), dateAdd(dateDue, 5, "days"),
                            includes(weekdays, format(day(dateAdd(dateDue, 6, "days")))), dateAdd(dateDue, 6, "days"),
                            includes(weekdays, format(day(dateAdd(dateDue, 7, "days")))), dateAdd(dateDue, 7, "days"),
                            false
                        )
                    ),
                
                recurUnit == "monthsonthelastday", if(conditionalDateNow >= lastDayBaseDate, nextLastBaseDate, lastDayBaseDate),
                
                recurUnit == "monthsonthefirstweekday", if(conditionalDateNow >= firstWeekdayBaseDate, nextFirstWeekday, firstWeekdayBaseDate),
                
                recurUnit == "monthsonthelastweekday", if(conditionalDateNow >= lastWeekdayBaseDate, nextLastWeekday, lastWeekdayBaseDate),
                
                includes(["days", "weeks", "months", "years"], recurUnit), 
                    if(dateBetween(conditionalDateNow, dateDue, "days") >= 1,
                        if(recurUnitLapseLength == ceil(recurUnitLapseLength),
                            dateAdd(dateDue, (recurUnitLapseLength + 1) * prop("Recur Interval"), recurUnit),
                            dateAdd(dateDue, ceil(recurUnitLapseLength) * prop("Recur Interval"), recurUnit)
                        ),
                        dateAdd(dateDue, prop("Recur Interval"), recurUnit)
                    ),
                false
            ),
            
            nextDueEnd, if(hasRange and nextDueStart != false, 
                dateAdd(nextDueStart, dueRange, "days"),
                false
            ),
            
            nextDue, if(hasRange and nextDueEnd != false, dateRange(nextDueStart, nextDueEnd), nextDueStart),
            
            if(
                debug == true,
                "---------\n" + prop("Task") + "\n---------" +
                "\npropDue: " + prop("Due") +
                "\npropRecurInterval: " + prop("Recur Interval") +
                "\npropRecurUnit: " + prop("Recur Unit") +
                "\npropDays: " + prop("Days (Only if Set to 1 Day(s))") +
                "\npropLocalizationKey: " + prop("Localization Key") +
                "\npropLocalizationKeyFormatted: " + 
                    map(
                        prop("Localization Key"), 
                        ifs(index == 0,
                            "\n\tweekdays: " + current,
                            index == 1, "\n\trecur units: " + current,
                            false
                        )
                    ) +
                "\npropUTCOffset: " + prop("UTC Offset") +
                "\nrecurUnit: " + recurUnit +
                "\nweekdays: " + weekdays +
                "\ndateDue: " + dateDue +
                "\ndateDueEnd: " + dateDueEnd +
                "\ntimeNow: " + timeNow +
                "\noffsetTimeNow: " + offsetTimeNow +
                "\ninUTC: " + inUTC +
                "\nhasValidOffset: " + hasValidOffset +
                "\nhasRange: " + hasRange +
                "\ndueRange: " + dueRange +
                "\nconditionalTimeNow: " + conditionalTimeNow +
                "\nconditionalDateNow: " + conditionalDateNow +
                "\nrecurUnitLapseLength: " + recurUnitLapseLength +
                "\nlastDayBaseDate: " + lastDayBaseDate +
                "\nfirstDayBaseDate: " + firstDayBaseDate +
                "\nfirstWeekdayBaseDate: " + firstWeekdayBaseDate +
                "\nlastWeekdayBaseDate: " + lastWeekdayBaseDate +
                "\nnextLastBaseDate: " + nextLastBaseDate +
                "\nnextFirstBaseDate: " + nextFirstBaseDate +
                "\nnextFirstWeekday: " + nextFirstWeekday +
                "\nnextLastWeekday: " + nextLastWeekday +
                "\nnextDueStart: " + nextDueStart +
                "\nnextDueEnd: " + nextDueEnd +
                "\nnextDue: " + nextDue,
                nextDue
            )
        ),
    "Error: Non-Whole or Negative Recur Interval"),
"")
Code language: JavaScript (javascript)

Next Due API

This formula helps to enable the Pipedream automation. It’s a separate property, as that allows the main Next Due formula to be formatted nicely for display in your Notion system.

if(test(prop("Next Due"), "Error") or empty(prop("Next Due")) or prop("Next Due") == false, "∅", "{\"start\":\"" + formatDate(dateStart(prop("Next Due")), "YYYY-MM-DD") + "\",\"end\":\"" + formatDate(dateEnd(prop("Next Due")), "YYYY-MM-DD") + "\"}")
Code language: JavaScript (javascript)

If you’re so inclined, you don’t have to leave everything in English. If you’re using Ultimate Tasks, or have copied the formulas from the advanced template linked above, you’ll also have a Localization Key property that looks like this (the full version has some commented out instructions we don’t need to repeat here):

[
["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"],

["Day(s)", "Week(s)", "Month(s)", "Year(s)", "Month(s) on the Last Day", "Month(s) on the First Weekday", "Month(s) on the Last Weekday"]
]
Code language: JavaScript (javascript)

If you simply swap out any of those entries with your own words for the weekdays or the recur units, you can use them in the Recur Unit and Days (Only if Set to 1 Day(s)) properties! If English isn’t your native language, your second brain can now work even better with your first. (Note that the English names will always work, no matter what other options you set up.)

If you’re using an older copy of Ultimate Brain or Ultimate Tasks that doesn’t contain the Next Due API and Localization Key properties in the All Tasks database, you likely started using your copy before we released our Formulas 2.0 in October of 2023.

This update includes new formulas – and updated to existing formulas – that are required for this recurring tasks workflow to function correctly.

Here are the upgrade guides you can follow for each template:

That’s the end of this tutorial, but if you want to learn more and take your Notion workspace to the next level, check out some of my other tutorials:

Also, if you enjoy this content and want more, consider joining my Notion Tips email list! I’ll keep you up to speed on my Notion courses, but also let you know when I publish new free tutorials and templates:

Notion Tips Newsletter

Get updates about my Notion templates and tutorials. Easily unsubscribe at any time.

Thanks for Subscribing!

A confirmation email just went out to the email address you provided. Once you click the confirmation link in it, you’ll be on the list! I’ll also send you a link to my other free templates.

Thanks for Subscribing!

A confirmation email just went out to the email address you provided. Once you click the confirmation link in it, you’ll be on the list! I’ll also send you a link to all my free Notion templates.

🤔 Have an UB Question?

Fill out the form below and I’ll answer as soon as I can! ~Thomas

🤔 Have a Question?

Fill out the form below and I’ll answer as soon as I can! ~Thomas