{"id":22973154,"url":"https://github.com/jderochervlk/rescript-remix","last_synced_at":"2025-04-02T07:14:44.187Z","repository":{"id":221223470,"uuid":"753796956","full_name":"jderochervlk/rescript-remix","owner":"jderochervlk","description":"ReScript bindings for Remix","archived":false,"fork":false,"pushed_at":"2024-02-06T21:50:07.000Z","size":8,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T17:44:26.553Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"ReScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jderochervlk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-06T20:08:42.000Z","updated_at":"2025-01-17T05:50:07.000Z","dependencies_parsed_at":"2024-10-20T17:18:01.794Z","dependency_job_id":null,"html_url":"https://github.com/jderochervlk/rescript-remix","commit_stats":{"total_commits":7,"total_committers":1,"mean_commits":7.0,"dds":0.0,"last_synced_commit":"1c5c2b47ef12a6d90bcf013c2086c05a8a704e45"},"previous_names":["jderochervlk/rescript-remix"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jderochervlk%2Frescript-remix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jderochervlk%2Frescript-remix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jderochervlk%2Frescript-remix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jderochervlk%2Frescript-remix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jderochervlk","download_url":"https://codeload.github.com/jderochervlk/rescript-remix/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246769968,"owners_count":20830771,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-14T23:39:56.564Z","updated_at":"2025-04-02T07:14:44.158Z","avatar_url":"https://github.com/jderochervlk.png","language":"ReScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @jvlk/rescript-remix\n\nReScript bindings, modules, and functions for Remix.\n\nRequires ReScript v11.\n\n\u003e This is a work in progress and is not complete\n\n## Installation\n\n```sh\nnpm install @jvlk/rescript-remix\n```\nUpdate `rescript.json` to include it in your dependencies.\n```json\n\"bs-dependencies\": [\n   \"@jvlk/rescript-remix\"\n],\n```\nIf you want to have `.res` files directly in the `app/routes` directory you will need to set the file extension to `.jsx` in `rescript.json`.\n\n\u003e Note: ReScript does not allow you to have `$` in file names so you will need to create a JavaScript file for routes with params such as `blog/$id.jsx` and import from your generated JavaScript files.\n\nAdd ReScript extenstions to Remix's ignored files so it doesn't try and load them in as routes and uses the generated `.jsx` files.\n```js\n// remix.config.js\nexport default {\n    ignoredRouteFiles: [\"**/.*\", \"**/*.res\", \"**/*.resi\"],\n}\n```\n## `root.js`\nYou can add types to Remix's links and meta functions\n```rescript\n@module(\"./style.css\")\nexternal styles: string = \"default\"\n\nlet links: Remix.Links.t = () =\u003e [Remix.Links.Href({rel: \"stylesheet\", href: styles})]\n\nlet meta: Remix.Meta.t = () =\u003e [\n  Remix.Meta.Content({name: \"viewport\", content: \"width=device-width, initial-scale=1\"}),\n  Remix.Meta.Title({title: \"My site\"}),\n  Remix.Meta.Content({\n    name: \"description\",\n    content: \"a website\",\n  }),\n  Remix.Meta.Charset({charset: \"UTF-8\"}),\n]\n\n@react.component\nlet make = () =\u003e {\n  \u003chtml lang=\"en\"\u003e\n    \u003chead\u003e\n      \u003clink rel=\"icon\" href=\"data:image/x-icon;base64,AA\" /\u003e\n      \u003cRemix.Meta /\u003e\n      \u003cRemix.Links /\u003e\n    \u003c/head\u003e\n    \u003cbody\u003e\n      \u003cmain\u003e\n        \u003cRemix.Outlet /\u003e\n      \u003c/main\u003e\n      \u003cRemix.Scripts /\u003e\n      \u003cRemix.LiveReload /\u003e\n    \u003c/body\u003e\n  \u003c/html\u003e\n}\n\nlet default = make\n```\n\n## Loader\nTo create a typed [loader](https://remix.run/docs/en/main/route/loader) you can use `Remix.MakeLoader` higher order module (functor). This will create a type for a loader as well as a typed `useLoaderData` hook that has a typed response.\n\n```rescript\n// _index.res\nmodule Data = {\n  type t = {posts: Posts.t} // type for the data returned by the loader\n  type params // route params\n  type context = { \"NODE_ENV\": string, \"API_KEY\": string } // context passed from the server\n}\n\nmodule Loader = Remix.MakeLoader(Data) // create a Loader module for this route\n\nlet loader: Loader.t /** use Loader.t to add typing to the exported loader function */= async ({context}) =\u003e {\n  let secret = context[\"API_KEY\"]\n  let data = await Posts.query(secret)\n  Loader.json( // this is Remix's json function typed to Data.t\n    {posts: data}, // if this doesn't match Data.t you'll get a type error\n    ~jsonOptions={ \n      headers: { // you can add headers to the response\n        \"Cache-Control\": \"max-age=300, s-maxage=3600\",\n      },\n    },\n  )\n}\n\n@react.component\nlet make = () =\u003e {\n  let {posts} = Loader.useLoaderData() // the data from the hook is fully typed\n  \u003cdiv\u003e\n    {posts\n    -\u003eArray.map(post =\u003e \u003cPost post /\u003e)\n    -\u003eReact.array}\n  \u003c/div\u003e\n}\n\nlet default = make // you have to export make as default for route files\n```\n\n## Actions\nTo create an action you can use `Remix.MakeAction`.\n\n```remix\nmodule ActionData = {\n  type t\n  type context = Env.context\n}\n\nmodule Action = Remix.MakeAction(ActionData)\n\nlet action: Action.t = async ({context, request}) =\u003e {\n    /** */\n    Js.null // actions expect you to return a value or null\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjderochervlk%2Frescript-remix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjderochervlk%2Frescript-remix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjderochervlk%2Frescript-remix/lists"}