We have quite a few SearchKit searches and now associated search forms associated with them. I am trying to understand how CiviCRM manages these files and what the best practice is for configuration management of these items.

The searches themselves along with any assoicated tables, lists etc appear to be stored in the database and thus survive a change in environment. If a form is created from a table or list within that search, CiviCRM then generates two files:

  1. afsearchMyNewSearch.aff.json
  2. afsearchMyNewSearch.aff.html

(I also seem to have a couple of older afformXXX.aff.son and html and not sure when they were created...)

These files seem to be created with the permissions of 640 with both owner and group being (in our case) www-data for Apache on my external environments (System Test/UAT/Prod)

Experimenting, once created, it looks to me that deleting these files will mean that they are lost forever and not recreated. If I make a change through CiviCRM, the files timestamp changes and all is good.

Trying to deploy a change from a repo causes a permission error if the file already exists on another controlled (i.e. not local) environment, because I did not deploy using the www-data user and we are trying to overwrite a read only file. It also changes the owner to the the deploying user. So this is a case where a change is made in just the form on a local dev environment (i.e. no database change) and we want to deploy this change.

I am trying to understand the best way to manage these forms as they would be time consuming to recreate. I know I can export and import each search plus their associated form/s, so perhaps storing those is a good target config item?

1 Answer 1


Your analysis is correct about where the data is stored:

  • SearchKit stores searches and displays in the database
  • Afform stores form layout and form config in .aff.html and .aff.json files, respectively.

When using the CiviCRM API, the differences in storage are invisible. You can call Civi\Api4\Afform::get() or Civi\Api4\SavedSearch::get(), (or ::save(), etc.) and it will read and write each from the correct place. The SearchKit "Export" button uses this api so that's why it is able to export everything (search, displays, and forms) into a single json string.

When you say you want the "best way", it depends on what you consider "best". Here are 2 good options:

  1. Best for simplicity: Use the SearchKit "Export" button. This outputs search, displays & forms into one json string you can copy and paste from one site to the other with just a few clicks. If older versions of those items exist on the target site, they will be overwritten.

  2. Best for version-control/distribution: Create an extension. SearchKit & FormBuilder were designed with extension packaging in mind. Use the command-line and type civix export SavedSearch 123 from your extension's directory to package e.g. the SavedSearch with id 123 plus all associated search displays and Afforms. You can put your extension in a git repository, and even share it in the CiviCRM Extensions Directory.

    When someone installs your extension, the searches & forms will immediately appear on their site, with the added benefit that any changes they make in the UI will be non-destructive: the local copy of the edited form doesn't overwrite the file in the extension, and there is a button in the UI to "revert" (which deletes the local file). Similarly the SavedSearch will have a "revert" button to overwrite local changes with the extension's version which is declared in a .mgd.php file.

  • 1
    That is extremely helpful Coleman - thank you. In the interim I'll go for simplicity - knowing that the re-import of the export will effectively 'upgrade' the incumbant set is useful. I had for safety deleted the old version first and reimported. I'll have a little side project to experiment with the Extension option as this will handle issues as the team grows in terms of who is allowed to make changes. The good news is that this has come about from the increased use of SearchKit which I think has been a very welcome addition to CiviCRM. Well done to the team.
    – ChumKui
    Jan 25 at 9:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.