Skip to content

Plugin initialization

comhon-project edited this page Jan 4, 2026 · 31 revisions

Import and use plugin

Table of contents


Before any usage of query-kit, you have to define your plugin configuration:

import { plugin } from "@query-kit/vue";

app.use(plugin, {
  // here is your configuration
})

Configurations

Requester

key type required
requester function or object false

The default requester that will fetch data from server. When registered globally via plugin options, it will be used by all QkitCollection components. Each component can override this default by passing its own requester as a prop.

If config is an object, it MUST contain a request property that contains a value of type function. The request function MUST return a promise that contains results of search request. The first parameter is the request data.

Example:

const config = {
  requester: async (data) => {
    const myData = {
      url: 'https://my.domain.com/endpoint',
      method: 'POST',
      ...data
    };
    return myRequester.fetch(myData);
  }
}

The injected data object contains the following values:

data.entity // the entity id (user, company, post, etc...)
data.order // the order of requested items
data.offset // the offset of the first returned result (pagination)
data.limit // the count limit of returned items (pagination)
data.filter // the request filters
data.properties // the properties that must be returned for each returned items

The requester MUST return an object that contains:

  • a count value that corresponds to the total items count that match the filter (not only the returned items count)
  • a collection that is an array of items.

Example:

{
  count: 245,
  collection: [
    {id:25, first_name: 'Jane'},
    {id:26, first_name: 'John'},
    /* ... */
  ]
}

Flattened items

Your requester may return flattened items or items with nested objects.

  • flattened item :
{
  first_name: 'Jane',
  favorite_fruits: ['apple', 'orange'],
  'company.brand_name': 'awesome brand name',
  'company.headquarter.address': '5 street nowhere'
}
  • item with nested values :
{
  first_name: 'Jane',
  favorite_fruits: ['apple', 'orange'],
  company: {
    brand_name: 'awesome brand name',
    headquarter: {
      address: '5 street nowhere'
    }
  }
}

If your requester returns flattened items, you MUST specify the flattened property in your requester object.

const config = {
  requester: {
    request: async (data) => {...},
    flattened: true,
  }
}

Entity Schema loader

key type required
entitySchemaLoader function or object true

The entity schema loader that will load your entities structures. If config is an object, it MUST contain a load property that contains a value of type function. The load function MUST return a promise that contains the entity structure. The first parameter is the entity id.

Each property, scope and scope parameter can have a name attribute that will be used as label if no translation is defined.

Example:

const entitySchemaLoader = async (entity) => {
  if (entity != 'user') {
    throw new Error('only user entity for example');
  }
  return {
    id: 'user',
    properties: [
      {id: 'id', type: 'integer'},
      {id: 'first_name', type: 'string', name: 'First Name'},
      {id: 'last_name', type: 'string', name: 'Last Name'},
      {id: 'birth_date', type: 'date', name: 'Birth Date'},
    ],
    unique_identifier: 'id',
    primary_identifiers: ['last_name', 'first_name'],
  }
}
const config = {
  entitySchemaLoader: entitySchemaLoader
}

Of course, schemas should be retrieved from server.

You can find an example of a schema that describe a user here.

Entity Translations loader

key type required
entityTranslationsLoader function or object false

You may define translations for your entity schema properties, scopes, and scope parameters. If config is an object, it MUST contain a load property that contains a value of type function. The load function MUST return a promise that contains translations. The first parameter is the entity schema id. The second is the current locale.

The returned object can contain:

  • properties: translations for entity properties (key is the property id)
  • scopes: translations for scope names (key is the scope id)
  • parameters: translations for scope parameters (key is scope id, value is an object where key is parameter id)

Example:

const entityTranslationsLoader = async (entity, locale) => {
  if (entity != 'user') {
    throw new Error('only user entity for example');
  }
  if (locale == 'en') {
    return {
      properties: {
        id: 'identifier',
        first_name: 'first name',
        last_name: 'last name',
        birth_date: 'birth date',
      },
      scopes: {
        active_users: 'active users',
        string_scope: 'string scope',
      },
      parameters: {
        string_scope: {
          value: 'value to search',
        },
      },
    }
  }
  if (locale == 'fr') {
    return {
      properties: {
        id: 'identifiant',
        first_name: 'prénom',
        last_name: 'nom',
        birth_date: 'date de naissance',
      },
      scopes: {
        active_users: 'utilisateurs actifs',
        string_scope: 'scope texte',
      },
      parameters: {
        string_scope: {
          value: 'valeur à rechercher',
        },
      },
    }
  }
  return {};
}
const config = {
  entityTranslationsLoader: entityTranslationsLoader
}

Of course, translations should be retrieved from server.

You can find an example of a translation schema that describe a user here.

Enum Schema loader

key type required
enumSchemaLoader function or object false

The enum schema loader that will load your enumeration structures. If config is an object, it MUST contain a load property that contains a value of type function. The load function MUST return a promise that contains the enum structure. The first parameter is the enum id.

Each enum case can have a name attribute that will be used as label if no translation is defined.

Example:

const enumSchemaLoader = async (enumId) => {
  if (enumId != 'gender') {
    throw new Error('only gender enum for example');
  }
  return {
    id: 'gender',
    cases: [
      {id: 'male', name: 'Male'},
      {id: 'female', name: 'Female'},
      {id: 'other', name: 'Other'},
    ],
  }
}
const config = {
  enumSchemaLoader: enumSchemaLoader
}

Enum Translations loader

key type required
enumTranslationsLoader function or object false

You may define translations for your enum cases. If config is an object, it MUST contain a load property that contains a value of type function. The load function MUST return a promise that contains translations. The first parameter is the enum id. The second is the current locale.

Example:

const enumTranslationsLoader = async (enumId, locale) => {
  if (enumId != 'gender') {
    throw new Error('only gender enum for example');
  }
  if (locale == 'en') {
    return {
      male: 'Male',
      female: 'Female',
      other: 'Other',
    }
  }
  if (locale == 'fr') {
    return {
      male: 'Homme',
      female: 'Femme',
      other: 'Autre',
    }
  }
  return {};
}
const config = {
  enumTranslationsLoader: enumTranslationsLoader
}

Request Schema loader

key type required
requestSchemaLoader function or object false

The request schema loader defines which properties are filterable and sortable for each entity. If config is an object, it MUST contain a load property that contains a value of type function. The load function MUST return a promise that contains the request schema. The first parameter is the entity id.

Example:

const requestSchemaLoader = async (entityId) => {
  if (entityId != 'user') {
    throw new Error('only user entity for example');
  }
  return {
    filtrable: {
      properties: ['first_name', 'last_name', 'birth_date'],
      scopes: ['active_users'],
    },
    sortable: ['first_name', 'last_name'],
  }
}
const config = {
  requestSchemaLoader: requestSchemaLoader
}

Icons

Icons

key type required
icons object false

You may register icons that will be used to display some contents, typically some buttons will use icons. By default, no icons are registered, so the associated text will be displayed instead. You can find all icons keys here.

Each key is the context where the icon will be used, each value determines which icon to display. Example:

const iconList = {
  add: 'fa-solid fa-plus', // will use default component and default prop name
  delete: { icon: "fa-solid fa-minus" }, // will use default component
  reset: { icon: "fa-solid fa-rotate-left", component: "Icon" }, // everything is defined
  previous: { icon: "fa-solid fa-previous", fade:"" }, // you may add some extra props
}

Icon component

key type required default
iconComponent string or object false i

The default component to use to display icon when component is not directly defined on icon. It may be a simple HTML tag or vue component.

Icon prop name

key type required default
iconPropName string false class

The default prop name where the icon value will be placed (only if defined icon is a simple string).

Complete icons config example

const config = {
  requester: /* ... */,
  icons: {
    add: 'fa-solid fa-plus',
  },
  iconComponent: 'i',
  iconPropName: 'class',
}

It will render the following icon:

<i class="fa-solid fa-plus"></i>

Using theme icons

The @query-kit/themes/default theme provides CSS icons that you can use (e.g. qkit-icon-plus, qkit-icon-cross, qkit-icon-refresh, etc.). Here is a complete example to register all icons using the theme icons:

const config = {
  icons: {
    add: { class: 'qkit-icon qkit-icon-plus', component: 'i' },
    add_filter: { class: 'qkit-icon qkit-icon-plus', component: 'i' },
    add_value: { class: 'qkit-icon qkit-icon-plus', component: 'i' },
    delete: { class: 'qkit-icon qkit-icon-cross', component: 'i' },
    close: { class: 'qkit-icon qkit-icon-cross', component: 'i' },
    previous: { class: 'qkit-icon qkit-icon-double-arrow-left', component: 'i' },
    next: { class: 'qkit-icon qkit-icon-double-arrow-right', component: 'i' },
    collapse: { class: 'qkit-icon qkit-icon-arrow-down', component: 'i' },
    down: { class: 'qkit-icon qkit-icon-arrow-full-down', component: 'i' },
    minus: { class: 'qkit-icon qkit-icon-minus', component: 'i' },
    reset: { class: 'qkit-icon qkit-icon-refresh', component: 'i' },
  },
}

Classes

key type required
classes object false

By default, rendered HTML elements will have some predefined classes, but you may override these class names to define your own classes. Note: if you don't use predefined themes, the default classes come without any style. So you can customize them as you want.

Example:

const config = {
  classes: {
    modal: 'my-modal-class',
    group: 'my-group-class',
    btn: 'my-btn-class',
  }
}

You can find all classes keys here.

Inputs

key type required
inputs object false

You may define custom inputs to use when rendering a filter. Basic property filters have predefined inputs (like string, integer, date, enumerations...) but for more complex properties that have a very specific type, this is typically where you should use custom inputs. You can override existing basic inputs too. A custom input is a component that allows the user to type the wanted filter value with your own inputs. You can see an example of a boolean input filter here.

To register the component, you will have to link it to a property type. Example:

const config = {
  inputs: {
    my_very_specific_type: 'my-very-specific-component',
    integer: 'my-integer-component-override',
  }
}

You can find all predefined inputs keys here.

By default when a filter is used with in or not_in operators, the filter component can be displayed several times. in

But you can define a custom component that directly manages these operators and it will be rendered only once. It will have to output the correct value according to the operator (an array of possible values when used with in or not_in). To do so, you will have to specify that your component must be displayed only once:

const config = {
  inputs: {
    my_other_specific_type: {
      component: 'my-other-specific-component',
      unique: true,
    },
  }
}

Cell renderers

key type required
cellTypeRenderers object false

You may define some callbacks or components to render values in the collection. Each callback or component must be associated to a type.

const config = {
  cellTypeRenderers: {
    integer: CellIntegerComponent,
    string: (cellValue, rowValue, property) => cellValue + ' suffix_int',
  }
}
key type required
cellPropertyRenderers object false

You may define some callbacks or components to render values in the collection. Each callback or component must be associated to an entity property.

const config = {
  cellPropertyRenderers: {
    user: {
      weight: (cellValue, rowValue, property) => cellValue + " suffix_weight",
    },
  }
}

The property renderers have a higher priority than type renderers.

Allowed operators

key type required
allowedOperators object false

The allowedOperators option allows you to define which operators will be usable in the request builder.

The default operators are:

{
  condition: {
    basic: [
      '=', '<>', '<', '<=', '>', '>=', 'in', 'not_in', 'like', 'not_like',
      'begins_with', 'doesnt_begin_with', 'ends_with', 'doesnt_end_with', 'null', 'not_null',
    ],
    enum: ['=', '<>', 'in', 'not_in', 'null', 'not_null'],
    date: ['=', '<>', '<', '<=', '>', '>=', 'in', 'not_in', 'null', 'not_null'],
    time: ['=', '<>', '<', '<=', '>', '>=', 'in', 'not_in', 'null', 'not_null'],
    datetime: ['=', '<>', '<', '<=', '>', '>=', 'in', 'not_in', 'null', 'not_null'],
    boolean: ['=', 'null', 'not_null'],
  },
  group: ['and', 'or'],
  relationship_condition: ['has', 'has_not'],
}

The basic operators are operators usable in condition that has a type not referenced in previous list (like integer, string ...). You can override any operator list with your own, you can specify new types with their allowed operators too.

Example:

const config = {
  allowedOperators: {
    condition: {
      string: ["=", "<>"],
      datetime: ["=", "<>"],
      array: ["=", "in"],
      my_custom_type: ["like", "not_like"],
    },
    group: ['and'],
  }
}

Each value will completely replace the default one.

Note that array operators are a restriction of the contained type operators. For example, if we have a property favorite_fruits that is an array of string:

 {
  id: 'favorite_fruits',
  type: 'array',
  children: {
    type: 'string'
  }
}

According to the previous config, allowed operators for this property are the intersection of array operators and string operators: ['=']

Default locale

key type required default
defaultLocale string false en

The default locale to use.

Fallback locale

key type required default
fallbackLocale string false en

The fallback locale to use when a translation is not found in current locale.

render HTML

key type required default
renderHtml boolean false false

By default, properties with type html are rendered as simple text to prevent XSS attacks. But you may render them as HTML by setting renderHtml to true.

const config = {
  renderHtml: true
}

Clone this wiki locally