You might want to share files and functionality between your application backend and frontend. This can help cut down on code duplication and ensure consistency between your server and client logic.
This can be helpful when building with React Router in framework mode or Remix that support server-side rendering, and use action and loader functions to handle data fetching and mutations on the server.
This guide will walk you through shared folder setup.
Setting up a shared folder
Follow these steps to start sharing files between you api backend and web frontend:
Create a new root level directory for the folder in your project structure. For example /shared.
Add your shared files to this folder. You can organize them into subdirectories as needed. Make sure to export any functions, classes, or constants you want to share. These exports can be imported into your api folder actions and routes using relative filepath imports.
For example, to import function utilFn from shared/index.ts:
api/actions/myGlobalAction.js
JavaScript
import { utilFn } from "../../shared";
export const run: ActionRun = async () => {
// call the function
const foo = utilFn();
return foo;
};
import { utilFn } from "../../shared";
export const run: ActionRun = async () => {
// call the function
const foo = utilFn();
return foo;
};
Or to import utilFn from shared/utils.ts:
api/actions/myGlobalAction.js
JavaScript
// Note the change to the import path
import { utilFn } from "../../shared/utils";
export const run: ActionRun = async () => {
// call the function
const foo = utilFn();
return foo;
};
// Note the change to the import path
import { utilFn } from "../../shared/utils";
export const run: ActionRun = async () => {
// call the function
const foo = utilFn();
return foo;
};
Update vite.config.mjs so Vite includes the shared folder. Reference your shared folder using the server.fs.allow option:
Gadget uses server.fs.allow under the hood to restrict Vite to the following paths:
["./.gadget/client", "./.gadget/server", "./node_modules", "./public", "./web"]. This is to ensure only the code
you want to make public is bundled and served.
Any additions made to server.fs.allow in your Vite config will be merged with these default paths.
After setting server.fs.allow, you can import from your shared folders from inside your project's web folder.
For example, to import function utilFn from shared/index.ts:
web/root.jsx
React
// ... other imports
import { utilFn } from "../shared";
// ... the rest of your frontend file
// ... other imports
import { utilFn } from "../shared";
// ... the rest of your frontend file
Or to import utilFn from shared/utils.ts:
web/root.jsx
JavaScript
// ... other imports
import { utilFn } from "../shared/utils";
// ... the rest of your frontend file
// ... other imports
import { utilFn } from "../shared/utils";
// ... the rest of your frontend file
Using resolve.alias for import aliases
You can also make use of Vite's resolve.alias option to create import aliases for your shared code. This can make your imports cleaner and easier to manage.
For example, to create an alias for a shared folder in vite.config.mjs: