Coding Standards
All Alokai modules follow specific code rules and patterns that can be useful during development. If you are creating a new module, we recommend following the same rules/patterns to ease your development process and provide consistency across the ecosystem.
Linting
Alokai storefronts use eslint, prettier as linting tools. Storefronts using next and nuxt contain a different set of rules - some are custom, but on top of those custom rules, common well-known plugins are used.
eslint rules
[
"next/core-web-vitals",
"plugin:@typescript-eslint/recommended",
"plugin:jsonc/recommended-with-json",
"plugin:perfectionist/recommended-natural",
]prettier rules
{
"singleQuote": true,
"printWidth": 120,
"plugins": ["prettier-plugin-tailwindcss"]
}eslint rules
[
"plugin:vue/vue3-strongly-recommended",
"@typescript-eslint"
]prettier rules
{
"endOfLine": "lf",
"semi": true,
"singleQuote": true,
"arrowParens": "always",
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 120,
"jsxSingleQuote": false,
"importOrder": ["^vue", "^(nuxt/(.*)$)|^(nuxt$)", "<THIRD_PARTY_MODULES>", "^[./]"],
"importOrderCaseInsensitive": true,
"plugins": ["@trivago/prettier-plugin-sort-imports"]
}Rules
We recommend writing code with our guidelines, which help produce readable, dry, and clean code.
- keep the correct file structure.
componentsandhooksnames are written withkebab-case- use the atomic approach when writing styles for components,
tailwindcssclasses are currently used in Alokai storefronts exportevery method or type that should be available in storefrontapitypings are available from@/typesalias import
- keep the correct file structure.
componentsandcomposablesnames are written withCamelCase- use the atomic approach while writing styles for components,
tailwindcssclasses are currently used in Alokai storefronts exportevery method or type which should be available in storefront- no need to
importnuxt auto imported methods such asref,computedetc apitypings are available from~/typesalias import
- write middleware methods and normalizers that follow middleware documentation guide
State
The most commonly needed data can be accessed from the state manager available in storefront.
Currently, we expose only a couple of data states available with given methods.
export const {
AlokaiProvider,
useSdk,
useSfCartState,
useSfCurrenciesState,
useSfCurrencyState,
useSfCustomerState,
useSfLocaleState,
useSfLocalesState,
} = createAlokaiContext<Sdk, SfContract>();Usage:
import { useSfCustomerState } from '@/sdk/alokai-context';
export default function ComponentName() {
const [customer] = useSfCustomerState();
}The most commonly needed data can be accessed from the state manager available in storefront.
Currently, we expose only a couple of data states available with given methods.
export const useSfState = defineStore("SfState", () => {
const cart = ref<SfCart | null>(null);
const customer = ref<SfCustomer | null>(null);
const currencies = ref<SfCurrency[]>([]);
const currency = ref<SfCurrency>();
const locale = ref<SfLocale>();
const locales = ref<SfLocale[]>([]);
return { customer, cart, currencies, currency, locales, locale };
});Usage:
<script setup lang="ts">
const { customer } = storeToRefs(useSfState());
</script>API Requests
To get data that is not available in the state, we can create our own hook/composable to get the desired data.
We can access a unified method via sdk.unified.methodName or use our own namespaced method sdk.quickOrder.methodName as the new methods documentation shows.
The next storefront uses @tanstack/react-query package for doing queries.
Example:
import { useQuery } from "@tanstack/react-query";
import { useSdk } from "@/sdk/alokai-context";
export function useQuickOrderCart() {
const sdk = useSdk();
return useQuery({
queryFn: () => sdk.quickOrder.getQuickOrderCart(),
queryKey: ["key"],
});
}We can access a unified method via sdk.unified.methodName or use our own namespaced method sdk.quickOrder.methodName as the new methods documentation shows.
The nuxt storefront uses native fetch functionality
export const useQuickOrderCart: UseCartReturn = () => {
const cart = useState('quick-order');
const fetchCart: FetchCart = async () => {
cart.value.loading = true;
cart.value.data = null;
try {
const fetchedCart = await useSdk().quickOrder.getQuickOrderCart();
cart.value.data = fetchedCart;
} catch {
// catch if fetch fail
}
cart.value.loading = false;
return cart.value.data;
};
return {
fetchCart,
...toRefs(cart.value),
};
};