Description
For businesses that treat every reservation as a conversation, not a checkout.
Appointly is an appointment booking system for WordPress that puts you back in the loop. Instead of automatic scheduling, customers submit booking requests — you review each one, send a personalized offer (with or without pricing), and the customer accepts or declines. Every reservation is deliberate, every price is yours to set, every customer gets a personal touch.
Perfect for photographers, consultants, event planners, freelancers, hair & beauty salons, tattoo artists, yoga and fitness studios, tutors — any service business where every reservation deserves a human in the loop.
Why Appointly?
Most booking plugins force automatic scheduling. Appointly is different:
- Customer picks a date (or timeslot) and submits an inquiry
- You review the request in the admin dashboard
- You send a personalized offer with a price and personal note
- Customer accepts or declines via a link in the email
- Booking confirmed — everyone gets notified
This offer workflow gives you the flexibility to adjust pricing, check availability manually, and add a personal touch before confirming any reservation.
Features:
- Booking Calendar — Beautiful, responsive appointment calendar with real-time availability, day-mode single-day booking
- Unlimited Services — Create as many services as you need, with title, description, image, and base price
- Personal Offer Workflow — Review every inquiry and send customised offers with automatic email delivery and one-click Accept / Decline links
- SMTP Email Delivery — Reliable email delivery with presets for Gmail, Outlook, Yahoo, iCloud, IONOS, Strato, World4You, Host Europe, ALL-INKL, Hetzner, and more
- Default Email Templates — Five polished HTML email templates (inquiry, admin notification, offer, confirmation, cancellation) with light and dark modes, fully translatable
- Dark Mode — Calendar automatically adapts to the visitor’s colour scheme
- Accessibility — WCAG AA compliant with keyboard navigation
- Gutenberg Block & Shortcodes — Add the calendar via block editor or shortcode
- Setup Wizard — Guided onboarding in four steps
- GDPR Ready — Consent checkbox on the booking form, personal data exporter and eraser integration, encrypted SMTP credentials
- Multilingual — Full i18n support. German translation included (de_DE, de_DE_formal, de_AT, de_CH, de_CH_informal)
Appointly Pro — coming soon:
Appointly Pro is a separate companion plugin that extends Appointly with 12 professional booking features. It is sold on https://appointly.tscholene.com for €2.99 per month and is NOT distributed through the WordPress.org Plugin Directory. The free plugin remains fully functional without Pro — Pro is an opt-in upgrade, not a lock on existing features.
Pro v1 features (launching in 2.1):
- Timeslot Scheduling — Time-based appointment slots per service. Customers pick a specific time, not just a date. Essential for yoga studios, therapists, consultants, and hair salons.
- Custom Service Fields — Build your own booking form with text, textarea, select, radio, checkbox, date, number, and file upload fields. Ask exactly what you need (« number of guests », « venue address », « special requests »).
- Service Addons & Upsells — Offer extras like « extra hour », « priority scheduling », « photo album », or « follow-up session » with configurable pricing and quantity.
- Blocked Dates — Block individual dates globally or per service, plus recurring patterns (« block every Sunday », « block December 20 – January 3 »).
- Multi-day Bookings — Date range bookings for multi-day events, workshops, retreats, and courses.
- iCal Feed — Subscribe to your bookings in Google Calendar, Apple Calendar, or Outlook for seamless two-way sync.
- Recurring Bookings — Automatic re-booking for weekly, bi-weekly, and monthly sessions. Ideal for yoga teachers, therapists, and consultants running regular appointments.
- Group Bookings — Multiple seats per time slot for classes, workshops, and small-group events.
- Customer Self-Service Portal — Customers reschedule or cancel their bookings via a secure email link, no admin contact required.
- Automatic Booking Reminders — Polite, on-brand reminder emails sent 24 hours before each appointment.
- Cancellation Policies — Rule-based fees and cutoff times (« cancellations under 24h incur a 50% fee ») enforced automatically.
- Custom Email Template Editor — Live preview editor with version history for all six email templates.
Coming in 2.2–2.5:
- Staff scheduling with per-staff calendars and load balancing
- Deposit collection via Stripe (your own Stripe keys, no middleman)
- WooCommerce integration with product-based bookings
- Advanced analytics with revenue reports and conversion funnels
- Zapier and webhook integrations for workflow automation
- Custom branding with logo and colours for your calendar and emails
- CSV and Excel export for accounting
- Priority email support
Learn more and join the waitlist at https://appointly.tscholene.com
Shortcodes & Block:
- Gutenberg Block: Search « Booking Calendar » in the block editor
[appointly_calendar]— Display the booking calendar[appointly_calendar service="2"]— Calendar for a specific service[appointly_form service="2"]— Standalone booking form
External services
Appointly loads Google Fonts on the WordPress admin pages so the admin UI can render with the Appointly brand typography (Instrument Serif for hero headings, Plus Jakarta Sans for body text, DM Mono for data labels). This is the only external service that the free plugin connects to.
- Service: Google Fonts (https://fonts.google.com)
- Purpose: Loading three web font families so the admin SPA renders with the Appointly brand typography
- Data sent: Your browser’s IP address and User-Agent are sent to
fonts.googleapis.comandfonts.gstatic.comwhen an admin user opens any Appointly admin page. No booking, customer, or plugin-specific data is transmitted. - When: Only when an authenticated WordPress administrator opens an Appointly admin page. Fonts are never loaded on customer-facing booking pages, iCal feed requests, or REST API calls.
- Terms of use: https://developers.google.com/fonts/faq#what_does_using_the_google_fonts_api_mean_for_the_privacy_of_my_users
- Privacy policy: https://policies.google.com/privacy
If you prefer to block Google Fonts entirely (for example in a privacy-hardened admin environment), the admin UI degrades gracefully to a system font stack (system-ui / BlinkMacSystemFont / Segoe UI / ui-serif / Menlo) and remains fully functional.
No other external services are contacted by the free plugin. Appointly does not call any payment providers (Stripe, PayPal), analytics services, license servers, or telemetry endpoints.
Appointly Pro — the separate companion plugin sold on https://appointly.tscholene.com — will, when installed, connect to appointly.tscholene.com for license validation (once per day) and plugin update checks. That connection is a feature of the Pro plugin and does not affect this free plugin. Appointly Pro ships with its own readme, privacy disclosures, and external-services documentation. The free plugin on this page does not make any requests to appointly.tscholene.com at runtime.
Build Instructions
The admin dashboard and the Gutenberg block are built with @wordpress/scripts (webpack). The uncompiled source is included in this distribution:
- Admin React source:
admin/src/(entry point:admin/src/index.js) - Block source:
blocks/src/(entry point:blocks/src/index.js)
To rebuild from source:
cd admin && npm install && npm run build
cd blocks && npm install && npm run build
Output goes to admin/build/ and blocks/build/ respectively.
The public frontend calendar (public/js/appointly-calendar.js) and stylesheet (public/css/appointly-calendar.css) are not compiled — they are vanilla JavaScript and CSS, human-readable as-is.
Captures d’écran

Admin dashboard with pending, offered, and confirmed booking counts plus recent requests 
Booking calendar on the front end — customers pick a date and submit an inquiry 
Bookings list with status filters, search, and one-click offer-workflow actions 
Booking detail view — customer info, timeline, and Send Offer / Accept / Decline actions 
Service editor with reorderable services, day or timeslot mode, and active-status toggle 
Settings page with booking defaults, SMTP email delivery, privacy, and uninstall behavior
Blocs
Cette extension offre 1 bloc.
- Booking Calendar
Installation
- Upload the
appointlyfolder to/wp-content/plugins/ - Activate the plugin through the ‘Plugins’ menu in WordPress
- Complete the setup wizard (Admin Booking)
- Add
[appointly_calendar]to any page or post, or use the « Booking Calendar » Gutenberg block - Optionally configure SMTP under Booking Settings Email Delivery
FAQ
-
Does this plugin require any external dependencies?
-
No PHP dependencies. The free plugin is fully self-contained and works offline. The admin SPA is bundled with @wordpress/scripts and ships with its own translation files.
Google Fonts (Instrument Serif, Plus Jakarta Sans, DM Mono) are loaded on admin pages only for the Appointly brand typography — this is documented in the « External services » section below. No fonts or third-party assets are loaded on customer-facing booking pages.
-
Can I use multiple calendars on one page?
-
Yes. Each
[appointly_calendar]shortcode creates an independent instance. -
How does the booking flow work?
-
- Customer selects a date (and optionally a timeslot) and fills out the booking form
- Customer and admin receive confirmation emails
- Admin reviews the request in Booking Bookings and clicks « Send Offer » with a price and personal note
- Customer receives an offer email with Accept / Decline buttons
- On acceptance, both parties receive the final confirmation email
-
Does it support multiple languages?
-
Yes. All strings are translatable via the standard WordPress .po/.mo system. German translations are included for de_DE, de_DE_formal, de_AT, de_CH, and de_CH_informal. The admin React bundle also ships per-bundle .json translation files so all admin UI strings render in the selected language.
You can override the customer-facing email language independently of the site language under Booking Settings General Email Language.
-
Can I customize the email templates?
-
The free plugin ships six default HTML email templates that are fully translatable through the standard WordPress translation system. If you need to rewrite the copy beyond translation, you can either override the templates in a child theme via the standard WordPress template loader, or wait for the live preview template editor coming with Appointly Pro.
-
Does it support payments?
-
The free plugin does not collect online payments directly. The booking flow supports manual / offline payment arrangements: when you send an offer, you state the price, the customer accepts, and you handle payment out-of-band (invoice, bank transfer, cash on arrival, etc.). Online payment collection via Stripe — using your own Stripe keys — will be available through Appointly Pro in a later release.
-
How is Appointly different from other booking plugins?
-
Unlike most booking and appointment plugins that push automatic scheduling, Appointly is built around a personal offer workflow. You receive booking requests, review them personally, and send customised offers. This gives service providers full control over their calendar, pricing, and customer communication — perfect for businesses where every reservation deserves a personal touch.
-
How do I get Appointly Pro?
-
Appointly Pro is a separate companion plugin, not yet publicly available. Visit https://appointly.tscholene.com to join the waitlist — we will email you when Pro launches. When you subscribe, you will receive a download link and a license key via email. You install Appointly Pro as a second plugin (Plugins Add New Upload Plugin) alongside this free plugin, paste your license key, and the Pro features activate. The installation takes about two minutes.
Appointly Pro is NOT distributed through the WordPress.org Plugin Directory. It is sold directly on appointly.tscholene.com via Lemon Squeezy, which handles EU VAT, subscriptions, failed payments, the customer portal, and refunds. Appointly Pro coexists with this free plugin in one admin menu — no duplicate menu entries, no configuration conflicts, and Pro can be removed independently without affecting any of your booking data.
Avis
Il n’y a aucun avis sur cette extension.
Contributeurs & développeurs
« Appointly » est un logiciel libre. Les personnes suivantes ont contribué à cette extension.
ContributeursTraduisez « Appointly » dans votre langue.
Le développement vous intéresse ?
Parcourir le code, consulter le SVN dépôt, ou s’inscrire au journal de développement par RSS.
Historique des changements
2.0.12
- Changed: Dashboard Pro upgrade card now reflects the 8 features actually shipped in Appointly Pro 0.6.0 (custom branding, email template editor, custom service fields, service addons, recurring bookings, direct booking / auto-confirm, blocked dates, customer self-cancel). Previous card listed 12 features, most of which were still on the roadmap.
- Changed: Pro CTA copy — « Join the waitlist » « Get Pro ». The Lemon Squeezy checkout is now live.
2.0.11
- Added: New filter hook
appointly_email_templateinSettingsRepository::get_email_template(). Free plugin behavior unchanged (no callback registered = defaults returned). Appointly Pro 0.6.0 registers a license-gated callback to inject admin-customized subject and body lines.
2.0.10
- Fixed: Installer now adopts legacy
wpbk_response_page_idwhen upgrading from pre-2.0.7 installs where the prefix migration may have been skipped — prevents a duplicate « Booking Response » page in the frontend menu. - Fixed: Auto-created Booking Response page is also excluded from
wp_list_pages()exclusion arrays (belt-and-suspenders on top of the existingget_pagesfilter) for broader block-theme compatibility.
2.0.9
- Added: Three new filter hooks (
appointly_branding_primary_color,appointly_branding_accent_color,appointly_branding_logo_url) used by frontend shortcodes and email templates. Free plugin behavior is unchanged (defaults to blue/green and the site name as text logo). Appointly Pro 0.5.0 uses these hooks to inject custom branding.
2.0.8
- Fixed: Service image picker in the service editor now opens the WordPress Media Library correctly. The admin bundle was missing
wp_enqueue_media(), sowindow.wp.mediawas unavailable and the picker silently fell back to an alert.
2.0.7
- Changed: Consolidated all internal prefixes to
appointly/APPOINTLY_/Appointly\per WordPress.org plugin review guidance. Database tables, options, hooks, constants, namespaces, REST namespace, script handles, JS globals, and CSS classes/custom properties were all unified under a single plugin-specific prefix. - Fixed: SMTP connection test no longer loads core PHPMailer files directly; uses
wp_mail()withwp_mail_failedhook for error capture. - Fixed: Booking Response page contrast (light-on-light text on some themes).
- Fixed:
manage_bookingscapability is now ensured on everyadmin_initas a safety net for file-overwrite upgrades that skip the activation hook. - Fixed: Cancelling a booking whose service has been deleted no longer produces a stuck « cannot cancel » error — the cancellation proceeds and skips the email step with a clear explanation.
- Internal: DB tables renamed from
wpbk_*toappointly_*. CSS custom properties renamed from--wpbk-*to--appointly-*. REST namespace changed fromwp-booking/v1toappointly/v1.
2.0.6
- Added: New filter hook
wpbk_booking_initial_statusso Appointly Pro can implement direct-booking workflows (per-service auto-confirm). - Added: Status-driven email routing for newly created bookings — confirmed bookings send
booking_confirmed+admin_new_booking, inquiry bookings keep the existing pair. - Added: New default email template
admin_new_bookingfor admin notifications on direct bookings. - Internal: DB version bumped to reflect new extension points.
2.0.5
- Added: Direct accept — mark a pending booking as confirmed without sending an offer (offline workflow).
- Added: Status change dialog with an « Inform customer via email » checkbox and optional admin note for every confirm/decline/cancel action.
- Added: Offered bookings can be manually cancelled by the admin (withdraw the offer).
- Added: Decline email template for manual admin declines (pending declined, offered declined).
- Added: Status-sensitive action buttons in both BookingDetail and the Bookings list, each with a tooltip explaining what the action does.
- Changed: The cancel booking flow now lets the admin opt out of the cancellation email.
- Changed: Offers sent without a price now show « Price on request » in the customer email instead of hiding the price box.
- Changed: Delete action only available on rows where no customer email has been sent yet (pending) or on finalized records (declined/cancelled).
- Fixed: Several pre-existing German translation errors surfaced during regeneration (
Acceptwas « Angebot annehmen »,Cancel Offerwas « Angebot annehmen »,Price on requestwas « Offene Anfragen »,Decline Bookingwas « Buchung stornieren »).
2.0.4
- WordPress.org plugin directory compliance release.
- Fixed: Review prompt now uses wp_register_script + wp_localize_script instead of echoing inline tags. Admin notice styled via CSS classes only (no inline style attributes).
- Fixed: All 7 raw SQL queries refactored to use %i placeholder + static literal prepare() strings. Sentinel-value pattern for dynamic filters (BookingRepository::list, ServiceRepository::list), N+1 loop for dynamic IN() clauses (BookingAdminController).
- Fixed: Variables in uninstall.php now carry the $wpbk_ prefix.
- Fixed: Core file includes (PHPMailer, wp-admin/upgrade.php) annotated with rationale comments explaining the allowed exception pattern.
- Fixed: Confirmed bookings can now transition to cancelled (supports Pro recurring series management).
- Changed: Shortcodes renamed from booking_* to appointly_* for prefix uniqueness (BREAKING — no existing public users):
[appointly_calendar],[appointly_form],[appointly_response]. - Changed: Gutenberg block namespace renamed from
wp-booking/calendartoappointly/calendar(reservedwp-prefix removed). - Changed: Requires WordPress 6.2+ (was 6.0+) for %i placeholder support.
- Internal: Dashboard hides the Pro upgrade card automatically when Appointly Pro is active.
2.0.3
- Added: Extension point for Pro booking detail sections
- Added: Filter hook for booking data array (wpbk_booking_to_array)
- Fixed: Service description now renders on the public booking form
2.0.2
- New: Opt-in destructive uninstall. Free 2.0.1 wiped all bookings, services, settings, and auto-created pages the instant you clicked Delete in the Plugins screen — with no opt-out. 2.0.2 flips this: by default, deleting the plugin now KEEPS all your data. If you want the old behavior, enable it explicitly under Settings General Uninstall Behavior. Matches the WooCommerce / Yoast / WPForms industry standard. Prevents surprise data loss when temporarily deactivating to troubleshoot.
- New: BookingDetail now shows custom field labels instead of raw keys (via
custom_fields_metaenrichment in the booking REST response). Bothget_bookingandupdate_bookingendpoints include the meta so labels persist across status changes. - New: BookingDetail renders custom field values type-aware — checkbox as Yes/No, numbers locale-formatted (1.234 in DE, 1,234 in EN), textarea with preserved line breaks.
- New: Public booking form inputs now apply
min,max, andmaxlengthHTML5 attributes from the field definition. Browser gives the customer immediate client-side feedback before hitting server-side validation. - New: Auto-created booking page is marked with
_wpbk_auto_createdpost meta. The uninstaller finds it via meta-query so it’s robust against admin renaming, recreating, or relocating the page. - These Free 2.0.2 changes ship bundled with Appointly Pro 0.2.0, which adds per-service Custom Fields. All BookingDetail / frontend-form improvements also benefit sites that never install Pro.
2.0.1
- Fix: Calendar showed no days on installs with « Plain » permalinks. The frontend JS naively concatenated
?year=...&month=...to the REST base URL, but the « ugly » REST URL form (/index.php?rest_route=/wp-booking/v1/) already contains a?, producing URLs with two?that the REST router treated as part of the route name and returned 404. Calendar now correctly uses&when the base URL already contains a query string. Affects all WP installs that haven’t switched permalinks to « Post name » — long-standing bug, was already broken in 2.0.0 and earlier. - New: Extension hooks for the upcoming Appointly Pro companion plugin (PHP filters, actions, JS extension points). See docs/PRO_HOOKS.md for the canonical contract.
- Fix: wpbk_email_placeholders filter was dead code due to an early return in EmailService::get_placeholders() — Pro features that injected custom email placeholders never received the filter call. Filter now fires correctly.
- Fix: wpbk_booking_declined action now passes both ($booking, $service) for consistency with all other lifecycle actions.
- New: BookingService::update_booking_date() public method for self-service rescheduling, fires wpbk_booking_rescheduled action.
- New: EmailService::render_preview() public method for live template preview rendering, with wpbk_email_template_keys filter to register additional template keys.
- New: wpbk_calendar_day_annotations PHP filter for per-day annotation strings on the public calendar.
- New: window.wpbkAdmin.proSettingsPanels and proBookingsListRowExtras JS extension points.
- New: window.wpbkConfig.proExtraFormFieldsHTML JS callback for injecting form HTML into the public booking form.
- No user-facing changes — Free 2.0.1 behaves identically to 2.0.0 when Pro is not installed.
2.0.0
- BREAKING — WordPress.org compliance release. Major rewrite to bring the plugin into full WordPress.org Plugin Directory compliance (Guideline 5: no trialware / locked features) and to reposition Pro as a separate companion plugin distributed outside the WP.org directory.
- Removed trialware gates. The license check and feature-gating system (
includes/Core/License.php,Limits.php) is gone entirely. Every existing feature is now unconditionally available: unlimited services, unlimited bookings, unlimited custom fields, unlimited add-ons per service, day and timeslot scheduling, automatic offer / confirmation emails, blocked dates calendar, multi-day bookings, and SMTP delivery are all free. - Pro feature strategy reworked. Stripe/PayPal payment integration, custom email template editor, conversion analytics, and custom branding are no longer part of the free plugin. These and other professional features will return in Appointly Pro — a separate companion plugin sold on appointly.tscholene.com (not on WordPress.org), launching in 2.1.0. The free plugin remains fully functional without Pro. Pro v1 will focus on recurring bookings, group bookings, customer self-service, automatic booking reminders, cancellation policies, and a live preview email template editor.
- New: Rebranded Admin UI. The admin dashboard has been rebuilt from scratch to match the appointly.tscholene.com brand identity — warm plum/violet and amber/gold palette, Instrument Serif hero headings, Plus Jakarta Sans body, DM Mono for data labels. New status pills, stat tiles with accent borders, and a prominent Appointly Pro upgrade card.
- New: Design tokens. All admin UI colours, typography, radii, and shadows are now driven by CSS custom properties scoped to
.wpbk-admin, mirroring the website design system. - Setup Wizard rewritten. The onboarding wizard is now a 4-step flow (Welcome, First Service, Email, Finish) with an honest Free vs Appointly Pro comparison. The previous license-entry and branding steps have been removed.
- New: Extension points for Appointly Pro. The plugin now exposes PHP action hooks (
wpbk_booking_created,wpbk_booking_offered,wpbk_booking_confirmed,wpbk_booking_declined,wpbk_booking_cancelled) and filter hooks (wpbk_booking_can_cancel,wpbk_calendar_availability,wpbk_email_placeholders) plus JavaScript extension globals (window.wpbkAdmin.proNavItems,window.wpbkAdmin.proRoutes) so the upcoming Appointly Pro plugin can dock in without requiring any further changes to the free plugin. These are silent no-ops when Pro is not installed. - Fixed: Compliance issues flagged by the WordPress.org review team. Removed the absolute « The only WordPress booking plugin » marketing claim. Updated the Plugin URI to point at https://appointly.tscholene.com. Fixed the Contributors list to use the correct WordPress.org username
tscholene. Added justification docblocks to every REST route usingpermission_callback => __return_true. Removed the redundantload_plugin_textdomain()init-time call (WordPress 4.6+ auto-loads from languages/ for wp.org plugins; the EmailService runtime call stays because it is load-bearing for the email_language override). - Database: the
wpbk_analyticstable is no longer created on activation. Existing installs retain the table until uninstall. Booking rows retain thepayment_methodandpayment_statuscolumns for backwards compatibility but new bookings leave them null. - Migration: existing license data in the
wpbk_settingsoption is ignored from 2.0.0 onwards and removed on uninstall. No user action required. - Migration: existing services with
booking_mode = 'timeslot'continue to work exactly as before — timeslot scheduling is now a free feature, not a Pro gate.
1.6.5
- Fix: Email preview in admin now renders in the configured email language instead of the admin’s personal profile locale — preview_template() is now wrapped in with_email_locale() like real sends
- Fix: Default email template subjects and bodies are now properly translatable. Previously the Installer wrote hardcoded English strings to the wpbk_email_templates option on activation, which could never be translated regardless of locale. SettingsRepository::get_default_templates() now returns __() wrapped strings resolved dynamically on every read.
- Migration: On upgrade, if the stored wpbk_email_templates option still contains the exact pristine English defaults from 1.5.0–1.6.3 (i.e. the user never customized them), the option is deleted so the translated fallback takes over. Any customization — even a single character — preserves the stored option untouched.
- i18n: Added German translations for all 12 default email subject/body strings (inquiry confirmation, admin notification, offer, booking confirmed, cancellation, payment received)
- DB version bumped to 1.5.0 to trigger the one-time email template migration
1.6.4
- Docs: Updated readme with full changelog for the 1.6.x series
- Maintenance: Synchronised Stable Tag with plugin header version
1.6.3
- i18n: Complete German translation of the admin UI (99% coverage, 418/420 React bundle strings) — dashboard, bookings, services, settings, analytics, onboarding, Pro upsell, email template editor, license manager
- i18n: Generated JavaScript translation JSON files for the admin React bundle (wp_set_script_translations needs per-bundle .json files in addition to .mo)
- i18n: Regenerated .pot template from source (1242 source references) and merged into all five German variants (de_DE, de_DE_formal, de_AT, de_CH, de_CH_informal)
- i18n: All 435 previously-untranslated admin and frontend strings now have German translations (formal « Sie » form across all variants)
1.6.2
- New: « Email Language » setting (Settings General) lets commercial users force customer emails into a specific language regardless of the WordPress site locale — useful when the admin UI is in one language but customers are in another
- Fix: Email templates now fully translatable — all hardcoded English labels (Date, Time, Service, Name, Email, Phone, Price, Custom Fields, Total Price, Payment Received, Accept Offer, Decline, etc.) wrapped in __()
- Fix: Addon table headers in offer and admin emails (Extra, Qty, Price) now translatable
- Fix: Plugin now calls load_plugin_textdomain() on init so shipped .mo files in /languages/ actually load (previously translations only worked if you dropped the .mo into wp-content/languages/plugins/)
- Fix: EmailService wraps every send in switch_to_locale() / restore_previous_locale() and reloads the text domain on switch (switch_to_locale does not do this for plugin text domains automatically)
- Fix: Email language defaults to get_locale() (site language) instead of determine_locale() — customer emails triggered from admin actions no longer go out in the admin’s personal profile language
- Fix: privacy_policy_url field is now sanitized and persisted correctly via SettingsController (was silently dropped before)
- i18n: 27 new German translations added for the email template labels across all five de_* variants
1.6.1
- Fix (critical): Service dropdown was invisible on the frontend for non-admin visitors whenever the page was served from a cache. Cause was a rest_cookie_invalid_nonce 403 — the cached HTML contained a nonce belonging to a different session, which WordPress’s rest_cookie_check_errors() rejected. fetchServices() then silently hid the dropdown on failure.
- Fix: CalendarShortcode and FormShortcode no longer embed a wp_rest nonce in wpbkConfig. All frontend REST endpoints use permission_callback => __return_true anyway, so the nonce was never protecting anything — it only created the cache-poisoning failure mode.
- Fix: fetchServices() now has an onError handler that surfaces a visible error message instead of leaving the dropdown hidden
- Maintenance: Plugin version bumped to bust browser caches of wpbk-calendar.js
1.6.0
- GDPR / Privacy: WordPress personal data exporter & eraser integration (Tools > Export / Erase Personal Data)
- GDPR / Privacy: Consent checkbox on booking form with configurable privacy policy URL
- GDPR / Privacy: Consent timestamp stored per booking (consent_given, consent_given_at)
- Security: SMTP credentials encrypted at rest (AES-256-CBC)
- Admin: New « Privacy » settings panel for privacy policy URL configuration
- i18n: Added consent label and validation strings (EN + DE)
1.5.0
- Complete plugin state with all features
- iCal calendar feed for Google/Apple/Outlook sync
- Theme mode setting (light/dark/auto) for calendar and emails
- SEO-optimized readme and review prompt after 5 bookings
- Date range booking support (multi-day)
1.0.0
- Initial release
- Booking calendar with day and timeslot modes
- Configurable services with custom fields and addons
- Offer-based booking flow
- 5 HTML email templates with dark mode
- React admin SPA
- SMTP support
- German translation

