---
title: Cookbook | Re-exporting loaders
contributors:
  - gioboa
  - aendel
  - extrordinaire
updated_at: '2023-12-15T11:00:00Z'
created_at: '2023-12-15T11:00:00Z'
---

import CodeSandbox, {CodeFile} from '../../../../components/code-sandbox/index.tsx';
import { Note, LongNote } from '~/components/note/note';

# Re-exporting loaders

`routeAction$` and `routeLoader$` are typically declared in route boundary files such as layout.tsx, index.tsx and plugin.tsx inside the routesDir directory
[here is docs](https://qwik.dev/docs/route-loader/).

Sometimes you would like to declare them outside of the route boundaries.
This may be useful when you want to create reusable logic or a library.
In such a case, it is essential that this function is re-exported from within the router boundary otherwise it will not run or throw exception.

## Solution

You can define `routeAction$` and `routeLoader$` in your custom path and re-export them in your layout.tsx, index.tsx and plugin.tsx files.

### Reusable logic example

Let's imagine we have a `routeLoader$` that checks whether our user is logged in or not.
It wouldn't make sense to copy and paste the same code into many parts of our code to make it work.
As per good practices, the ideal method is to centralize the logic.
Here in this example we declare `routeAction$` and `routeLoader$` in a centralized file so we can then reuse it in our files.

Example with `./shared/loaders.ts`
<CodeFile src="/src/routes/demo/cookbook/re-exporting-loaders/shared/loaders.ts" >
```tsx
import { routeAction$, routeLoader$ } from '@qwik.dev/router';

export const useCommonRouteAction = routeAction$(async () => {
  // ...
  return { success: true, data: ['Qwik', 'Partytown'] };
});

export const useCommonRouteLoader = routeLoader$(async () => {
  // ...
  return ['Mitosis', 'Builder.io'];
});
```
</CodeFile>

Now you can use your common `routeAction$` and `routeLoader$` in paths like this one `./src/routes/index.tsx`.

<CodeFile src="/src/routes/demo/cookbook/re-exporting-loaders/" >
```tsx
import { component$ } from '@qwik.dev/core';
import { Form } from '@qwik.dev/router';
import { useCommonRouteAction, useCommonRouteLoader } from './shared/loaders';

// As mentioned, here we are re-exporting them
export { useCommonRouteAction, useCommonRouteLoader };

export default component$(() => {
  const commonRouteAction = useCommonRouteAction();
  const commonRouteLoader = useCommonRouteLoader();

  return (
    <div class="flex justify-around text-xl">
      <Form action={commonRouteAction}>
        <div class="mb-2">CommonRouteAction</div>
        <div class="mb-4">response:</div>
        <div class="text-lg font-bold mb-4">
          {commonRouteAction.value?.data.join(' ') || ''}
        </div>
        <button type="submit">Submit</button>
      </Form>
      <div>
        <div class="mb-2">CommonRouteLoader</div>
        <div class="mb-4">response:</div>
        <div class="text-lg font-bold mb-4">{commonRouteLoader.value.join(' ')}</div>
      </div>
    </div>
  );
});
```
</CodeFile>

<CodeSandbox src="/src/routes/demo/cookbook/re-exporting-loaders/"  style={{ height: '15em' }} />

### Preventing issues with <u>indirect</u> `routeLoader$` usage (Third-Party Libraries Example)

It may happen that we need to integrate third-party libraries over which we have no control over how it works.
Let's think for example about integrating a payment method into our application.
We are provided with a component to integrate into the page, but we have no control over what happens under the hood of this component.

If these third-party components rely on `routeLoader$` or `routeAction$` functions, we must manually re-export and register those inside 
a component that exists within the route boundary. This is necessary so the Qwik optimizer can detect and include them during the build.

<LongNote title="Manual Registration Required Before v2.0">
Starting in Qwik v2.0, manual registration will no longer be needed. However, until then, the optimizer may **miss** `routeLoader$` functions if they’re used inside components that are **conditionally rendered** (e.g., toggled with a signal).

If you don’t manually register the loader in these cases, you may encounter undefined behavior. <u>Avoid skipping this step</u>.
</LongNote>


#### Here is our code:

<CodeSandbox src="/src/routes/demo/cookbook/re-exporting-loaders/third-party/index.tsx"  style={{ height: '20em' }}>
```tsx
import { component$ } from '@qwik.dev/core';
import { ThirdPartyPaymentComponent, useThirdPartyPaymentLoader } from './third-party-library';

// As mentioned, here we are re-exporting the third-party loader
export { useThirdPartyPaymentLoader } from './third-party-library';

export default component$(() => {
  
  // Manually register the loader so the optimizer sees it
  useThirdPartyPaymentLoader()

  return (
    <section>
      <ThirdPartyPaymentComponent />
    </section>
  );
});
```
</CodeSandbox>

#### Here is the library code:

<CodeFile src="/src/routes/demo/cookbook/re-exporting-loaders/third-party/third-party-library.tsx" >
```tsx
import { component$ } from '@qwik.dev/core';
import { routeLoader$ } from '@qwik.dev/router';

export const useThirdPartyPaymentLoader = routeLoader$(() => {
  return { name: 'John Doe' };
});

export const ThirdPartyPaymentComponent = component$(() => {
  const thirdPartyPaymentLoader = useThirdPartyPaymentLoader();
  return (
    <div
      class={[
        'w-96 h-56 m-auto rounded-xl relative text-white font-bold shadow-2xl',
        'transition-transform transform hover:scale-110 bg-gray-600',
      ]}
    >
      <div class="w-full px-8 absolute top-8">
        <div class="flex justify-between">
          <div class="">
            <p>Name</p>
            <p class="tracking-widest">{thirdPartyPaymentLoader.value.name}</p>
          </div>
          <img class="w-12 h-12" src="/logos/qwik-logo.svg" />
        </div>
        <div class="pt-1">
          <p class="font-medium">Card Number</p>
          <p class="tracking-wider">4642 3489 9867 7632</p>
        </div>
        <div class="pt-6 pr-6">
          <div class="flex justify-between text-xs">
            <div>
              <p class="font-medium">Valid</p>
              <p class="tracking-wider">11/15</p>
            </div>
            <div>
              <p class="font-medium">Expiry</p>
              <p class="tracking-wider">03/25</p>
            </div>
            <div>
              <p class="font-medium">CVV</p>
              <p class="tracking-wider">···</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
});
```
</CodeFile>
