CSR for Craft CMS

Configuration

Settings live at CSR → Settings. The link appears for admins when allowAdminChanges is on, which is also where Craft's own settings are edited. The screens that write project config (Sites, field layouts, statuses, teams, SLAs and form questions) deploy with the rest of your project config.

General

SettingDefaultWhat it does
What the help centre is calledHelp CenterUsed in page titles and breadcrumbs.
The public knowledge baseOnArticles, categories, search and ratings. Off makes them all 404.
Default help centre pathkbWhere the index, search and category pages live on a site that hasn't set its own on the Sites screen.
The support formOnWhere tickets are raised.
The customer's own ticket pageOnWhere a customer reads and replies to a ticket, reached from the link in every email.
Close resolved tickets after7 daysZero leaves them resolved.
A reply reopens a closed ticket for30 daysAfter this, a reply to an old thread doesn't reopen it.
Delete tickets after0 (never)Permanently deletes resolved and closed tickets. Nothing goes to the trash.
First ticket number1000Nobody wants to be told they are ticket 1.
Assign new ticketsLeave them unassignedPro. In turn, or to whoever has the fewest open tickets — among the members of the ticket's team when it has one.
Hand the conversation to PigeonOffOnly shown when Pigeon is installed. See Usage.

Resolved and closed are kept separate on purpose. Resolved is the desk saying the problem is fixed. Closed is what happens when the customer doesn't disagree. The gap between the two is when someone can reply "that didn't fix it" and carry on the same conversation.

Knowledge base

SettingDefaultWhat it does
Articles per page20In the built-in category and search pages.
Related articles to show4When an author has not picked any, the most-read articles in the same category fill in.
"Popular" means the last30 daysThe window for popular articles and top searches.
Ask readers whether an article helpedOn
Ask what they were looking for after a "no"OnShows a comment box only after a no.
Record what people search forOnPowers the search reports. The visitor is stored as a salted hash.
Count article viewsOn
Keep searches for365 daysZero keeps them forever. Lite keeps 30 days regardless.
Shortest search worth running2Characters, for the live dropdown.
Suggestions in the live dropdown8
Words that mean the same thingnoneOne group per row, comma separated: refund, money back, chargeback.

A synonym match scores lower than the word the visitor actually typed, so an article called Refunds still ranks first for "refund".

Sites

Each site has its own article settings, like a section's site settings:

SettingDefaultWhat it does
New articles are enabled hereOn
Article URI formatkb/{slug}Empty gives this site no article pages.
TemplatenoneOptional. Empty uses CSR's own article page.
The help centre index lives atkbWhere this site's index, search and category pages live. Empty uses the Default help centre path.

Category pages sit at <index>/category/<handle>. Categories get their own segment so that an article and a category with the same slug can't end up at the same URL.

Changing a URI format, or giving a new site its article settings, queues every article to be saved again, so their URLs update without anybody running a command. php craft resave/csr-articles does the same by hand.

A named Template is rendered by CSR's own article controller, with the same variables as article.twig (article, category, related, existingVote), so restricted articles are still refused and views and search clicks are still counted.

Support form

SettingDefaultWhat it does
Where the form livessupportA path on every site.
Where a customer reads their own ticketsupport/ticketMust be different from the form path.
The link stays usable for0 (forever)Days after the last reply.
Suggest articles as they typeOnThe suggestions panel. Included in Lite.
Start suggesting after8Characters typed before CSR looks. Shorter queries match everything.
How many to show3
Ask them to look firstOffSending within two seconds of the suggestions appearing brings them into view and sends the form when the two seconds are up. A pause, never a wall. Needs the runtime script.
Anyone can raise a ticketOnOff requires visitors to sign in.
Default priorityNormalLow, Normal, High or Urgent.
Let people choose the priorityOffIf this is off, a priority in the request is ignored.
Let people attach filesOffAttachments also need a volume.
Volume, Sub-foldernone, ticketsFiles are stored under <sub-folder>/<ticket number>.
Allowed file typespng,jpg,jpeg,gif,webp,pdf,txt,log,csv,zip
Largest file, Files per message10 MB, 3

Attachments are always served through CSR and only to the person the ticket belongs to, never from the asset's own URL. A file that is too big or has the wrong type is skipped, and the ticket is still created.

Notifications

SettingDefaultWhat it does
Who hears about new ticketsnoneOne address per line. The assigned agent and the ticket's team are added automatically.
Confirm to the customer / Tell the desk when a ticket is raisedOn
Email the customer when the desk replies / Email the desk when the customer repliesOn
Send through the queueOnSo a slow mail server never makes the support form hang.
Put a clock on ticketsOffPro. Switches SLAs on.
Tell the desk when a target is missedOnPro.
Ask "how did we do?" after a ticket is resolvedOffPro. Emails the customer a link to rate the ticket 1–5, and shows the rating on their ticket page.
Wait before asking24 hoursPro. Not sent if the ticket has been reopened, rated or merged in the meantime.
Opening hours, time zone, days the desk is shut9–5, Mon–FriPro. Used by policies that only count opening hours.

The wording of each email is edited under Settings → Email → System Messages. See Usage.

Spam

SettingDefaultWhat it does
Honeypot field namecsrCompanyUrlp, token, action and siteId are refused, because Craft uses those.
Refuse submissions faster than3 secondsZero turns the check off.
Tickets one address may raise per hour5Counted per email address, not per IP. Zero is unlimited.
Replies one address may post per hour20From the customer's own ticket pages, counted separately from new tickets. Zero is unlimited.
Store the sender's IP addressOn
CAPTCHA provider, site key, secretNoneCloudflare Turnstile or Google reCAPTCHA (v2 checkbox). The key and secret can be environment variables.

CSR runs the checks from cheapest to most expensive, so most junk is refused before any network request. CSR's own support form and ticket page render the CAPTCHA widget with {{ craft.csr.captcha() }}; a template of your own needs the same line. See Troubleshooting for what each check means for your templates.

Field layouts, statuses, teams, SLAs and questions

  • Article fields: the article body. CSR keeps the category, visibility, keywords and ratings itself and leaves the rest to your fields.
  • Ticket fields: what your team records about a ticket after it arrives. Customers never see these.
  • Statuses: a name, a colour, and a kind (New, Open, Pending, Resolved or Closed), which is what CSR actually uses. One status is where new tickets land. Any status can email the customer when a ticket moves to it, with its own Twig subject and body or the generic message. Lite allows five statuses.
  • Teams (Pro): a name, a shared address that is copied on the team's tickets, and members. Members are stored in the database, not project config, because user IDs differ between environments. A category routes its tickets to a team with Route its tickets to on the category's own screen; a child category with no team uses its parent's.
  • Service levels (Pro): first-reply and resolution targets in minutes, whether to count only opening hours, conditions (priority, category, team, where the ticket came from), breach alerts, and escalation to a team a set number of minutes after the first-reply deadline. Policies are tried in order and the first match wins, so put the most specific ones at the top.
  • Form questions (Pro): text, multi-line text, email, URL, number, date, dropdown, radio buttons, checkboxes, a single checkbox, or hidden. Each can be required, and each can be limited to certain categories.

Config file

Any setting can be set in config/csr.php, which takes precedence over the control panel. It supports Craft's per-environment keys:

<?php

use craft\helpers\App;

return [
    '*' => [
        'kbPath' => 'help',
        'supportPath' => 'help/contact',
        'portalPath' => 'help/ticket',
        'synonyms' => [['refund', 'money back', 'chargeback']],
        'notificationRecipients' => ['support@example.com'],
    ],
    'production' => [
        'captchaProvider' => 'turnstile',
        'captchaSiteKey' => '$TURNSTILE_SITE_KEY',
        'captchaSecret' => '$TURNSTILE_SECRET',
        'autoAssign' => 'roundRobin',
    ],
];

autoAssign (Pro) is none, roundRobin (whoever got a ticket longest ago) or leastBusy (whoever has the fewest open tickets). Auto-assignment only picks agents who can answer tickets, and only from the ticket's team if it has one. The CAPTCHA key and secret accept $ENV_VAR references, here or on the Spam screen.

businessHours takes ['monday' => ['open' => '09:00', 'close' => '17:00'], …], and holidays takes a list of YYYY-MM-DD dates.