A Svelte-optimized Axios wrapper that provides reactive request handling, built-in caching, and simplified state management for HTTP requests.
npm install axios svelte-axios-plus
axios
is a peer dependency and needs to be installed explicitly
Version 2.x.x of svelte-axios-plus
is built for Svelte 5.
Users running Svelte 4 applications should continue using the latest 1.x.x version of svelte-axios-plus
.
Full documentation for v1 is available in the v1 Readme.
<script lang="ts">
import axiosPlus from 'svelte-axios-plus';
const { req, refetch } = axiosPlus('https://reqres.in/api/users?delay=1');
</script>
{#if req.loading}
<p>Loading...</p>
{:else if req.error}
<p>Error!</p>
{/if}
<div>
<button onclick={() => refetch()}>Refetch</button>
<pre>{JSON.stringify(req.data, null, 2)}</pre>
</div>
The package exports one default export and named exports:
import axiosPlus, {
resetConfigure,
configure,
clearCache,
load,
getConfig,
makeAxiosPlus
} from 'svelte-axios-plus';
The main function to execute HTTP requests.
url|config
- String URL or axios request configoptions
- Configuration objectmanual
(default false
) - Controls automatic request execution on component render. Use the refetch
function returned when invoking axiosPlus
to execute the request manually.useCache
(default true
) - Enables/disables request caching. It doesn't affect the refetch
function returned by axiosPlus
.autoCancel
( true
) - Controls automatic cancellation of pending requests[!IMPORTANT]
Default caching behavior can interfere with test isolation. See testing section.
An object with the following properties:
req
- Request state objectdata
- Response data from the axios success responseloading
- Current request status (true if the request is in progress, otherwise false)error
- Error details if request failedresponse
- Complete success response objectrefetch(configOverride?, options?)
- Manual request executionconfig
- Same config
object as axios
, which is shallow-merged with the config object provided when invoking axiosPlus
.options.useCache
(default false
) - Enables/disables request cachingcancel()
- Cancels pending requestsreset(force?)
- Resets the request state to its initial stateforce
(default false
) - Forces a reset even if the request is in progress by cancelling the pending requestResets all configuration options back to default values.
Default values:
axios
- StaticAxios
instancecache
- new LRUCache({ max: 500, ttl: 1000 * 60 })
defaultOptions
- {manual: false, useCache: true, autoCancel: true}
defaultLoadOptions
- {useCache: true}
Configures the axiosPlus
instance with custom options.
axios
- Custom Axios instance or Axios-like clientcache
- LRU cache instance or false to disable cachingdefaultOptions
- Default options for all requests. It will be merged with the out of the box default options.manual
- Controls automatic request execution on component render. Use the refetch
function returned when invoking axiosPlus
to execute the request manually.useCache
- Enables/disables request caching. It doesn't affect the refetch
function returned by axiosPlus
.autoCancel
- Controls automatic cancellation of pending requestsdefaultLoadOptions
- Default options for load
functionuseCache
- Enables/disables request cachingClears the current LRU cache if caching is enabled.
Performs a one-time request with optional caching.
url|config
- String URL or axios request configoptions.useCache
(default true
) - Enables/disables request cachingA promise with the following properties:
data
- Response data from the axios success responseerror
- Error details if request failedresponse
- Complete success response objectReturns the current configured options.
An object with the following properties:
axios
- Current Axios instancecache
- Current LRU cache instance or false if disableddefaultOptions
- Default options configurationdefaultLoadOptions
- Default load options configurationCreates a new axiosPlus
instance with optional initial configuration.
axios
- Custom Axios instance or Axios-like clientcache
- LRU cache instance or false to disable cachingdefaultOptions
- Default options for all requests. It will be merged with the out of the box default options.manual
- Controls automatic request execution on component render. Use the refetch
function returned when invoking axiosPlus
to execute the request manually.useCache
- Enables/disables request caching. It doesn't affect the refetch
function returned by axiosPlus
.autoCancel
- Controls automatic cancellation of pending requestsdefaultLoadOptions
- Default options for load
functionuseCache
- Enables/disables request cachingPreconfigured axiosPlus
instance with the same methods as the package's named exports but limited to the axiosPlus
instance returned by makeAxiosPlus
.
Unless provided via the configure
function, svelte-axios-plus
uses the following defaults:
axios
- StaticAxios
instancecache
- new LRUCache({ max: 500, ttl: 1000 * 60 })
defaultOptions
- {manual: false, useCache: true, autoCancel: true}
defaultLoadOptions
- {useCache: true}
These defaults may not suit your needs, for example:
In such cases you can use the configure
function to provide your custom implementation of both.
<script lang="ts">
import axiosPlus, { configure } from 'svelte-axios-plus';
import { LRUCache } from 'lru-cache';
import Axios from 'axios';
const axios = Axios.create({
baseURL: 'https://reqres.in/api'
});
const cache = new LRUCache({ max: 10 });
configure({ axios, cache }); // configure globally
axiosPlus.configure({ axios, cache }); // configure per instance
</script>
On the client, requests are executed when the component renders using the Svelte $effect
rune.
This may be undesirable, as in the case of non-GET requests. By using the manual
option you can skip the automatic execution of requests and use the return value of axiosPlus
to execute them manually, optionally providing configuration overrides to axios
.
In the example below we use axiosPlus
twice. Once to load the data when the component renders, and once to submit data updates via a PUT
request configured via the manual
option.
<script lang="ts">
import axiosPlus from 'svelte-axios-plus';
const { req: getReq } = axiosPlus('https://reqres.in/api/users/1');
const { req: putReq, refetch } = axiosPlus(
{
url: 'https://reqres.in/api/users/1',
method: 'PUT'
},
{ manual: true }
);
async function updateData() {
try {
await refetch({
data: {
...getReq.data,
updatedAt: new Date().toISOString()
}
});
} catch (error) {
// Handle errors
}
}
</script>
{#if getReq.loading || putReq.loading}
<p>Loading...</p>
{/if}
{#if getReq.error || putReq.error}
<p>Error!</p>
{/if}
<div>
<button onclick={updateData}>Update data</button>
<pre>{JSON.stringify(putReq.data || getReq.data, null, 2)}</pre>
</div>
The cancel
function allows you to terminate pending requests, whether initiated automatically or through the refetch
method.
In the example below we use axiosPlus
with its automatic and manual requests.
We can call the cancellation programmatically or via controls.
<script lang="ts">
import axiosPlus from 'svelte-axios-plus';
let pagination: Record<string, number> = $state({ per_page: 6, page: 1 });
const { req, refetch, cancel } = axiosPlus(() => ({
url: 'https://reqres.in/api/users?delay=5',
params: pagination
}));
function handleFetch() {
pagination = { ...pagination, page: pagination.page + 1 };
}
async function externalRefetch() {
try {
await refetch();
} catch (error) {
// Handle errors
}
}
</script>
<div>
<button onclick={handleFetch}>Refetch</button>
<button onclick={externalRefetch}>External Refetch</button>
<button disabled={!req.loading} onclick={cancel}>Cancel Request</button>
{#if req.loading}
<p>...loading</p>
{/if}
<pre>{JSON.stringify(req.data, null, 2)}</pre>
</div>
For server-side requests containing sensitive data like API keys, use the async load
function instead of axiosPlus
. This integrates with SvelteKit's server-side data loading pattern.
In Svelte you can load data for your page via the +page.server.ts
file. The logic inside that file is only executed on the server. You can read more about that topic over here.
Create a +page.server.ts
file for your route
import axiosPlus from 'svelte-axios-plus';
interface PageServerLoad {
(): Promise<{
rdata: any;
error: string;
}>;
}
export const load: PageServerLoad = async () => {
const { data, error, response } = await axiosPlus.load('https://reqres.in/api/users?delay=1');
return {
rdata: data,
error: JSON.stringify(error, null, 2)
};
};
export const ssr = true;
export const csr = false;
Access data in +page.svelte
<script lang="ts">
interface Props {
data: {
rdata: any;
error: string;
};
}
let { data }: Props = $props();
</script>
<pre>Data: {JSON.stringify(data.rdata, null, 2)}</pre><p>Error: {data.error}</p>
For applications requiring different API configurations or caching strategies, makeAxiosPlus
enables creation of independent axiosPlus
instances.
This factory function returns a configured axiosPlus
instance based on provided configuration.
Tip Use this to create pre-configured instances as an alternative to the global
configure
function.
<script lang="ts">
import axios from 'axios';
import { makeAxiosPlus } from 'svelte-axios-plus';
const customAxiosPlus = makeAxiosPlus({
axios: axios.create({ baseURL: 'https://reqres.in/api' })
});
const { req, refetch } = customAxiosPlus('/users?delay=1');
</script>
{#if req.loading}
<p>Loading...</p>
{/if}
{#if req.error}
<p>Error!</p>
{/if}
<div>
<button onclick={() => refetch()}>Refetch</button>
<pre>{JSON.stringify(req.data, null, 2)}</pre>
</div>
While axiosPlus
is not inherently reactive to argument changes, you can enable reactivity through:
$derived
rune$effect
rune with the refetch
functionFor detailed information on Svelte function reactivity, refer to:
Notable Feature: When using an options state object with axiosPlus
, changes to this object automatically trigger reactive updates by default (see example below).
<script lang="ts">
import axiosPlus, { type AxiosPlusOptions } from 'svelte-axios-plus';
let options: AxiosPlusOptions = $state({
manual: true,
autoCancel: true,
useCache: true
});
// The following two axiosPlus calls are equivalent and will react to 'options' state changes
const { req: req1 } = axiosPlus('https://reqres.in/api/users?delay=5', options);
const { req: req2 } = axiosPlus('https://reqres.in/api/users?delay=5', () => options);
</script>
The axiosPlus
function offers flexible configuration through dynamic function arguments. You can pass both the config and options as functions, enabling axiosPlus
to automatically respond to state changes in these function arguments.
Here's what makes this powerful:
axiosPlus(() => config)
axiosPlus(config, () => options)
axiosPlus(() => config, () => options)
The best part? You have complete flexibility - use functions for dynamic state values and plain objects for static configurations. This means you can mix and match based on your needs.
axiosPlus
internal state integrity, with request cancellation controlled through the autoCancel
flagaxiosPlus
implementation<script lang="ts">
import axiosPlus, { type AxiosPlusOptions } from 'svelte-axios-plus';
let pagination: Record<string, number> = $state({});
let options: AxiosPlusOptions = $state({
manual: true,
autoCancel: true,
useCache: true
});
const { req } = axiosPlus(
() => ({
url: 'https://reqres.in/api/users?delay=5',
params: pagination
}),
() => options
);
</script>
Using the $derived
rune with axiosPlus
triggers a complete function reinitialization whenever any referenced state values are modified.
$derived
rune wrapper around the axiosPlus
functionaxiosPlus
function resets its internal state and terminates active requests, regardless of the autoCancel
setting<script lang="ts">
import axiosPlus, { type AxiosPlusOptions } from 'svelte-axios-plus';
let pagination: Record<string, number> = $state({});
let options: AxiosPlusOptions = $state({
manual: true,
autoCancel: true,
useCache: true
});
const { req } = $derived(
axiosPlus(
{
url: 'https://reqres.in/api/users?delay=5',
params: pagination
},
options
)
);
</script>
Using the $effect
rune to trigger the refetch
function on state changes provides a robust and controlled approach to handling reactive updates.
axiosPlus
initializationaxiosPlus
internal state integrity, with request cancellation controlled solely by the autoCancel
setting$effect
rune, increasing code footprintconfigOverride
and useCache
options, excluding other settings like manual
and autoCancel
<script lang="ts">
import axiosPlus, { type RefetchOptions } from 'svelte-axios-plus';
let pagination: Record<string, number> = $state({});
let options: RefetchOptions = $state({
useCache: true
});
const { req, refetch } = axiosPlus(
{
url: 'https://reqres.in/api/users?delay=5'
},
options
);
$effect(() => {
async function fetchData() {
try {
await refetch({ params: pagination }, options);
} catch (error) {
// Handle errors
}
}
fetchData();
});
</script>
The project includes a very simple playground example to play around with the library and its features.
npm install
npm run dev
Renamed the following interfaces
ResponseValues
-> RequestState
Options
-> AxiosPlusOptions
Updated the AxiosPlusResult
type
// Old type
type AxiosPlusResult<TResponse = any, TBody = any, TError = any> = [
{
loading: Readable<boolean>;
data: Readable<TResponse | undefined>;
error: Readable<AxiosError<TError, TBody> | null>;
response: Readable<AxiosResponse<TResponse, TBody> | undefined>;
},
RefetchFunction<TBody, TResponse>,
() => void,
() => void
];
// New type
type AxiosPlusResult<TResponse = any, TBody = any, TError = any> = {
req: Readonly<RequestState<TResponse, TBody, TError>>;
refetch: RefetchFunction<TBody, TResponse>;
cancel: () => void;
reset: (force?: boolean) => void;
};
axiosPlus
Due to the AxiosPlusResult
type update the usage of axiosPlus
has changed (see example below).
Further request state is now returned through the req
property, and direct destructuring is no longer supported to maintain reactive state.
Version 1.x.x usage example
<script lang="ts">
import axiosPlus from 'svelte-axios-plus';
const [{ loading, data, error }, refetch] = axiosPlus('https://reqres.in/api/users?delay=1');
</script>
{#if $loading}
<p>Loading...</p>
{:else if $error}
<p>Error!</p>
{/if}
<div>
<button on:click={refetch}>Refetch</button>
<pre>{JSON.stringify($data, null, 2)}</pre>
</div>
Version 2.0.0 usage example
<script lang="ts">
import axiosPlus from 'svelte-axios-plus';
const { req, refetch } = axiosPlus('https://reqres.in/api/users?delay=1');
</script>
{#if req.loading}
<p>Loading...</p>
{:else if req.error}
<p>Error!</p>
{/if}
<div>
<button onclick={() => refetch()}>Refetch</button>
<pre>{JSON.stringify(req.data, null, 2)}</pre>
</div>
Testing components that use axiosPlus
may experience test isolation issues due to built-in caching. To ensure proper test isolation, call the configure function before each test to disable the cache:
configure({ cache: false });
svelte-axios-plus
requires ES6 Promise support. Check your environment's compatibility here.
For environments without ES6 Promise support, use some polyfill like this one ES6 promise.
svelte-axios-plus
is heavily inspired by axios-hooks.
It began as a simple port of the axios-hooks
package to svelte, but over the time I added some additional features that are not present in the axios-hooks
package.
Dependencies: