PCOWidget — All Configuration Options

Live demo using Emmanuel Lutheran Church data  ·  API key 18dc5c27c3e7ee647b3ff31626a10d16

Already have a widget? Paste it into the Widget Builder to load its settings, or to find out why it is not doing what you expect.New

🛠 Build your own script interactively →

Layouts — data-layout

Built

Six layouts are available. Default is table if omitted. Every layout opens the full event card when an event is clicked or tapped.

table — Month grid (default)
<script src="https://api.pcowidget.com/v1/calendar-widget.js?key=18dc5c27c3e7ee647b3ff31626a10d16" data-layout="table"></script>

week — 7-day strip
<script src="..." data-layout="week"></script>

list — Row list with thumbnails
<script src="..." data-layout="list"></script>

cards — Image cards
<script src="..." data-layout="cards"></script>

simple — Service tiles (minimal)
<script src="..." data-layout="simple"></script>

tiles: Image grid (click a tile to open it)
<script src="..." data-layout="tiles" data-tag="Website-Home" data-months-ahead="4" data-rows="1"></script>

Open tiles on hover: data-hover-preview="1"New Tiles open on a click or tap, like every other layout. Add data-hover-preview="1" and a tile also opens when the pointer rests on it for about half a second. This was the default until October 2026; an embed that still has data-hover-preview="0" keeps working and now simply matches the default.

tiles with data-hover-preview="1" (rest the pointer on a tile)
<script src="..." data-layout="tiles" data-tag="Website-Home" data-months-ahead="4" data-rows="1" data-hover-preview="1"></script>

Tag filter — data-tag

Built

Filter to events that have a specific Planning Center tag. Comma-separate multiple tag names for OR logic — e.g. data-tag="Youth,Women's Ministry" shows events tagged either tag.

Filter by tag "Worship Services" — simple layout
<script src="..." data-layout="simple" data-tag="Worship Services"></script>

Tag + featured combined — list layout
<script src="..." data-layout="list" data-featured="true" data-tag="Worship Services"></script>

Campus filter: data-campusNew

Built

Give each campus its own page from one Planning Center calendar. Name a campus and the widget shows only that campus's events; comma-separate for OR, exactly like data-tag. Leave the attribute off and every campus shows, so a single-campus church never sets it.

Where the campus comes from. Planning Center's Calendar API has no campus field on an event, so this matches against the Campus tag group you already keep in Planning Center: the tags in that group are your campus names. Type them exactly as they read there. If your group is named something else, "Locations" or "Sites" or a name of your own, naming any one campus in it is enough for the widget to find the rest.

One campus, one page
<script src="..." data-layout="cards" data-campus="Downtown" data-title="What's On at Downtown"></script>
Two campuses in one widget, OR logic
<script src="..." data-layout="list" data-campus="Downtown, Westside"></script>
Campus page that still carries the churchwide events
<script src="..." data-layout="cards" data-campus="Downtown" data-campus-untagged="1"></script>

Untagged events are a decision, not an oversight. Most churches leave the churchwide items untagged: Christmas Eve, the all-church workday, the annual meeting. Those belong on every campus page rather than none, and data-campus-untagged="1" is what puts them there. Left off, a campus page is strict and lists only what is tagged for it. Decide by what untagged means on your own calendar: if it usually means a staff meeting or a room hold, leave it off.

Campus and tags are separate controls. data-campus decides which events appear. data-show-tags decides which chips are visible on them. They combine happily: data-campus="Downtown" data-show-tags="Ministry" gives a Downtown page whose cards carry ministry chips and no campus chip, since every event on the page is the same campus anyway.

No live example on this page: the demo calendar belongs to a single-campus church with no Campus tag group, so a working embed here would render an empty box rather than show you anything. Build one against your own key in the Widget Display Builder instead.

Rolling 7-day window — data-this-week

Built

Shows only events in the next 7 days from today. Perfect for "This Week's Services" homepage sections. Works with any layout.

This week — simple layout (homepage use case)
<script src="..." data-layout="simple" data-this-week="true" data-title="This Week's Services"></script>

This week — cards layout
<script src="..." data-layout="cards" data-this-week="true"></script>

Week navigation — data-allow-week-nav + data-nav-align

Built

Adds Prev / Next week navigation buttons to the simple layout. The label shows "This Week" / "Next Week" / "+N Weeks" and clicking it returns to the current week. data-nav-align controls button alignment: left, center (default), or right.

Week nav — align center (default)
<script src="..." data-layout="simple" data-allow-week-nav="true" data-nav-align="center" data-title="This Week's Services"></script>

Week nav — align left
<script src="..." data-layout="simple" data-allow-week-nav="true" data-nav-align="left"></script>

Week nav — align right
<script src="..." data-layout="simple" data-allow-week-nav="true" data-nav-align="right"></script>

Show past events — data-include-past

Built

By default, events that have already ended are hidden. Set data-include-past="true" to include them — useful for archive or recap pages. Default: false.

Include past — list layout
<script src="..." data-layout="list" data-include-past="true"></script>

Exclude past (default behavior shown explicitly)
<script src="..." data-layout="list" data-include-past="false"></script>

Also accepted: "1" / "0", "True" / "False", "TRUE" / "FALSE".

Event count — data-limit

Built (max 50) "ALL" not supported yet

Controls how many events to fetch. Default: 50. Currently capped at 50 — "ALL" is not yet a valid value.

Limit 3 — good for homepage previews
<script src="..." data-layout="cards" data-limit="3"></script>

Limit 6 — cards grid
<script src="..." data-layout="cards" data-limit="6"></script>

Columns: data-columns

Built (simple, tiles, cards)

How many go across, 1 to 8. Defaults: 2 on simple, 4 on tiles. On cards it only applies when set; leave it off and cards fit themselves to the space. Every layout steps down to fewer columns as the screen narrows. The examples below use simple.

1 column
<script src="..." data-layout="simple" data-columns="1"></script>

2 columns (default)
<script src="..." data-layout="simple" data-columns="2"></script>

3 columns
<script src="..." data-layout="simple" data-columns="3"></script>

Shadow style — data-shadow

Built

Controls the container shadow color theme. Default: blue.

shadow="blue" (default)
<script src="..." data-layout="simple" data-shadow="blue"></script>

shadow="burgundy"
<script src="..." data-layout="simple" data-shadow="burgundy"></script>

shadow="standard" (neutral gray)
<script src="..." data-layout="simple" data-shadow="standard"></script>

Custom heading — data-title

Built

Overrides the heading displayed above the widget. Any string is valid. If omitted, the widget auto-generates a heading from the filter context (e.g. "Featured Events", "Worship Services").

Custom title on simple layout
<script src="..." data-layout="simple" data-title="This Week's Services"></script>

Custom title on list layout
<script src="..." data-layout="list" data-title="Upcoming Events"></script>

Mount target — data-target

Built

Mount the widget into an existing element by DOM ID instead of auto-creating a container after the script tag. Useful when you need the widget inside a specific page region.

↑ This div has id="my-custom-container" — the widget will mount here

Widget mounted into #my-custom-container
<div id="my-custom-container"></div> <script src="..." data-layout="simple" data-target="my-custom-container"></script>

Useful Combinations

Built

Real-world patterns combining multiple options.

Homepage: This week's worship services, 3-col, with week nav, burgundy shadow
<script src="..." data-layout="simple" data-tag="Worship Services" data-this-week="true" data-allow-week-nav="true" data-columns="3" data-shadow="burgundy" data-title="This Week's Services"></script>

Events page: Full month calendar, featured events only
<script src="..." data-layout="table" data-featured="true" data-title="Featured Events"></script>

Ministry page: Cards, limited to 6, with tag filter
<script src="..." data-layout="cards" data-tag="Worship Services" data-limit="6" data-shadow="standard" data-title="Worship Events"></script>

Archive page: List with past events included
<script src="..." data-layout="list" data-include-past="true" data-limit="20" data-title="Past Events"></script>

Multi-tag OR filter — data-tag="tag1,tag2"

Built

Comma-separate tag names to show events matching ANY of the listed tags (OR logic). Case-insensitive. Single tag still works exactly as before.

Two tags OR — list layout
<script src="..." data-layout="list" data-tag="Worship Services,Special Events" data-title="Worship & Special Events"></script>

Tag OR + featured filter — cards
<script src="..." data-layout="cards" data-tag="Worship Services,Special Events" data-featured="true" data-limit="6"></script>

Hide end time — data-hide-end-time

Built

Show only the start time — hides the “– 10:30 AM” portion. Applies to simple, cards, and list layouts. Useful for service tiles where end times add clutter.

Hide end time — simple layout
<script src="..." data-layout="simple" data-hide-end-time="true" data-title="Services (start times only)"></script>

Hide end time — list layout
<script src="..." data-layout="list" data-hide-end-time="true"></script>

Hide widget when empty — data-hide-if-empty

Built

When zero events match the current parameters, the widget normally renders a "No upcoming events found" box that takes up space on the page. With data-hide-if-empty="true", the entire container collapses to nothing — no border, no message, no space. Works with all layouts and all filter combinations.

Primary use case: tag-filtered or this-week widgets on pages where that ministry or service may have no upcoming events. Without this flag you get an empty box; with it the section disappears entirely until events exist.

Hide if empty — tag-filtered simple layout
<script src="..." data-layout="simple" data-tag="Men's Ministry" data-this-week="true" data-hide-if-empty="true" data-title="Men's Ministry This Week"></script>

If no Men's Ministry events exist this week, nothing renders above — no box, no space.

Hide if empty — featured cards
<script src="..." data-layout="cards" data-featured="true" data-hide-if-empty="true" data-title="Featured Events"></script>

Custom empty message — data-empty-message

BuiltNew

When nothing matches, the widget shows "No upcoming events at this time." Use data-empty-message to say something more useful instead: point visitors at your weekly service times, another page, or a phone number. Up to 200 characters.

Note: this is ignored if you also set data-hide-if-empty, since in that case the widget removes itself entirely and there is no message to show.

Default wording
<script src="..." data-layout="cards" data-tag="NoSuchTagExists"></script>

Custom wording
<script src="..." data-layout="cards" data-tag="NoSuchTagExists" data-empty-message="Nothing scheduled right now. Join us Sundays at 10:30am."></script>

Choose which tags are visible — data-show-tags

BuiltNew

Some events carry six or eight Planning Center tags. On a card layout every one of them renders as a chip, which pushes the title and details downward and makes the card look cluttered. data-show-tags is a whitelist: only the tags you name stay visible.

Match by group, not by tag. Planning Center organizes tags into tag groups (Campus, Ministry, Category, and so on). Entries in data-show-tags match either a tag group name or an individual tag name. Naming the group is almost always the better choice: with data-show-tags="Campus", a campus you add next year shows up on its own, with no change to your embed code.

This is display only. It changes which chips you see, never which events appear. To filter the events themselves, use data-tag. The two work together: filter with data-tag, then tidy up the chips with data-show-tags.

All tags (default)
<script src="..." data-layout="cards" data-limit="2"></script>

No tag chips at all
<script src="..." data-layout="cards" data-limit="2" data-show-tags="0"></script>

One tag group only
<script src="..." data-layout="cards" data-limit="2" data-show-tags="Ministry"></script>

Named tags only
<script src="..." data-layout="cards" data-limit="2" data-show-tags="Website,Highlighted"></script>

Skip to the next month with events — data-auto-advance

BuiltNew

It is the 28th of the month, the next event is nine days away, and the widget shows an empty box. data-auto-advance="2" tells the widget: if the month the visitor lands on has nothing, look ahead up to two months and show the first one that does. The month heading follows the jump, so the widget reads "September 2026" instead of claiming to show an empty August.

Keep the number small. Accepts 1 through 6. Jumping five months ahead to surface one lonely event is about as useful to a visitor as showing them last month's calendar. One or two is usually right.

Only on arrival. Auto-advance applies to the month the visitor first lands on. Once they click the month arrows, they get exactly the month they asked for, empty or not. Silently skipping past a month someone deliberately navigated to makes the arrows feel broken.

This is not an aggregate window. Auto-advance picks which single month the visitor lands on, and the month arrows still move one month per press from there. If what you want is "gather the next four months of Youth events into one grid", that is a different attribute: data-months-ahead.

Combining with data-hide-if-empty: auto-advance runs first. The widget only removes itself if no month inside the lookahead window has any events. If you want the widget to disappear the moment the current month is empty, leave auto-advance off.

Without auto-advance
<script src="..." data-layout="cards" data-tag="Men's Ministry"></script>

Look ahead up to 3 months
<script src="..." data-layout="cards" data-tag="Men's Ministry" data-auto-advance="3"></script>

Gather several months into one set — data-months-ahead

BuiltNew

The rest of the widget answers "which month am I looking at". This one answers a different question: what is coming up. data-months-ahead="4" pulls every matching event from today out to four months into a single set and drops the month arrows entirely. Point it at a tag and you have a thumbnail strip of everything in that series that is still ahead, which is what a church home page usually wants above the fold.

It is a window from today, not a run of calendar months. On the 26th of August, data-months-ahead="4" covers 26 August to 26 December. Nothing that has already finished appears, so the set shrinks through the month and refills as new events are scheduled. Accepts 1 through 12.

No month navigation, on purpose. There is no month being displayed, so there is nothing for arrows to move between and the toolbar is not drawn at all. That also means data-auto-advance and data-this-week have nothing to do here: both pick a window, and this one has already picked it. The Widget Display Builder drops them from the embed code for you.

Pair it with data-rows or data-limit. Four months of a busy calendar is a lot of tiles. A row cap keeps the block a fixed height and shows the soonest events, which is the point of putting it on a home page.

list, cards, tiles and simple only. table and week draw a calendar grid whose rows are the weeks of one month, so there is nowhere to put a four-month span. They ignore the attribute rather than quietly showing you one month of it.

Nothing in the whole window? Then the church genuinely has nothing scheduled that far out, and no setting can invent one. Add data-hide-if-empty="1" and the widget removes itself from the page instead of announcing the gap.

One month at a time (the default)
<script src="..." data-layout="tiles" data-columns="3" data-rows="1"></script>

The next 4 months, gathered
<script src="..." data-layout="tiles" data-columns="3" data-rows="1" data-months-ahead="4"></script>

Show repeating events once: data-first-only

BuiltNew

A weekly meeting is one event in Planning Center with a date every week, and the widget normally shows every one of those dates. Over a four-month window that is sixteen tiles of the same Tuesday night, crowding out the Christmas concert the widget was put there to promote. data-first-only shows each repeating event once, at its next date, with a +3 more dates note. The popover lists the other dates.

Name the tags it applies to, or say all. data-first-only="Men's Ministry, Women's Ministry" folds only repeating events carrying one of those tags; everything else shows every date as before. A tag group name works too and covers every tag in the group. data-first-only="all" folds every repeating event on the calendar. Tag names are matched without regard to case, and a curly apostrophe matches a straight one.

One entry per event, not one per tag. A Men's Ministry tag that carries both the weekly men's meeting and a one-off Men's Christmas Breakfast shows both: the meeting once, the breakfast on its own. Folding by tag instead would hide the breakfast behind whichever meeting came first, which is exactly the special event you want seen.

The count is within the window on screen. In month view "+3 more dates" means three more this month; with data-months-ahead it means across the whole window. Dates that have already finished are not counted. data-limit and data-rows count distinct events, so data-rows="1" on four columns is four different events, never the same meeting four times.

list, cards, tiles and simple only. table and week are a calendar, and a calendar that showed a weekly meeting on only its first Thursday would make the other Thursdays look empty. They ignore the attribute. Leave it off entirely and nothing about the widget changes.

Every date (the default)
<script src="..." data-layout="tiles" data-tag="Website-Home" data-columns="3" data-months-ahead="4"></script>

Men's Ministry shown once
<script src="..." data-layout="tiles" data-tag="Website-Home" data-columns="3" data-months-ahead="4" data-first-only="Men's Ministry"></script>

Styling to match your website

BuiltNew

Every church can make the widget look like its own website, on every plan, without writing CSS. Pick one brand colour with data-accent and the whole widget follows it: buttons, date badges, times, today's date, chips and the event card. The hover shade, the pale tint behind chips, and black or white text on buttons are all worked out from that one colour. The Widget Builder has a colour picker and a live preview.

The other options. data-font="inherit" uses your website's font, or name one, such as data-font="Lato", if your website already loads it. data-accent-hover sets the exact colour buttons turn under the pointer, when the shade worked out from your brand colour is not the one you want. data-frame="flat" keeps the border and drops the shadow; data-frame="none" drops the border, shadow and background so the widget sits directly on your page. data-corners="square", data-text-size="large", and data-show-title="0" to hide the heading. Leave them all off and nothing changes.

Light colours stay readable. A pale brand colour such as gold would make white button text and gold event times hard to read, so the widget darkens the text shade and switches button text to black whenever that reads better. The gold example below shows it.

Dark websites. data-mode="dark" turns the widget, its cards and the event card dark with light text, and lightens your brand colour's shades so they stay readable. The last example below sits on a dark panel to show it.

The Starter credit. On the free plan the small "Powered by PCOWidget" line stays under the widget and takes on your brand colour. The Pro plan removes it. See The Starter credit in our Terms.

Named font and hover colourNew
<script src="..." data-layout="list" data-rows="3" data-accent="#7a1f3d" data-accent-hover="#c2410c" data-font="Georgia"></script>

Standard look (no styling attributes)
<script src="..." data-layout="tiles" data-tag="Website-Home" data-months-ahead="4" data-columns="3" data-first-only="Men's Ministry"></script>

Navy, square, no frame, site font, larger text
<script src="..." data-layout="tiles" data-tag="Website-Home" data-months-ahead="4" data-columns="3" data-first-only="Men's Ministry" data-accent="#4a5a8c" data-font="inherit" data-frame="none" data-corners="square" data-text-size="large" data-show-title="0"></script>

A light brand colour stays readable
<script src="..." data-layout="cards" data-columns="2" data-rows="1" data-accent="#f2c230"></script>

Green, border only
<script src="..." data-layout="list" data-rows="3" data-accent="#2f6f4f" data-frame="flat"></script>

Dark mode, on a dark page
<script src="..." data-layout="tiles" data-tag="Website-Home" data-months-ahead="4" data-columns="3" data-first-only="Men's Ministry" data-mode="dark" data-accent="#c9a227"></script>

Approval and publish levels — data-visibility

BuiltNew

Planning Center tracks two separate things about an event: where it sits in your approval workflow (approved, pending, rejected) and whether you have published it to Church Center. data-visibility walks down both at once. Each level shows everything the level above it showed, plus one more class of event.

Level What appears Use it for
published (default) Approved and published to Church Center. Your public website. Always.
approved The above, plus approved events not yet published. Checking what is ready to publish.
pending The above, plus events awaiting approval. Watching the approval queue.
rejected The above, plus rejected events. Everything. Troubleshooting a missing event.
This is a staging tool. Put a second widget on a staff-only page with data-visibility="pending" and your team can see what is moving through approval and how it will look once live, while the public page keeps showing only finished, published events. Never set anything other than published on a page visitors can reach.

No approval workflow? Nothing changes. If your church does not use Planning Center's approval process, every event counts as approved and only the publish setting matters.

If an event is missing from your site, check this first. The most common cause of "why isn't my event showing up" is an event that was never published in Planning Center. Open the event in PCO Calendar and confirm it is visible in Church Center. Temporarily switching a staff page to data-visibility="rejected" shows the whole calendar, which makes it obvious where the event actually sits.

Public page (default, no attribute needed)
<script src="..." data-layout="cards" data-limit="3"></script>

Staff preview page showing the whole calendar
<script src="..." data-layout="cards" data-limit="3" data-visibility="rejected" data-title="Full Calendar (Staff View)"></script>

data-include-unpublished="true" still works as shorthand for data-visibility="approved". If both are set, data-visibility wins.