{"id":13726596,"url":"https://github.com/ahrefs/melange-react-intl","last_synced_at":"2026-02-12T04:21:03.417Z","repository":{"id":40371152,"uuid":"358367118","full_name":"ahrefs/melange-react-intl","owner":"ahrefs","description":"ocaml ppx to reduce boilerplate from react-intl messages","archived":false,"fork":false,"pushed_at":"2025-03-18T07:04:36.000Z","size":229,"stargazers_count":13,"open_issues_count":6,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-03T00:17:03.668Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Reason","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ahrefs.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":null,"funding":null,"license":"LICENSE","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":"2021-04-15T19:14:28.000Z","updated_at":"2025-03-18T07:04:41.000Z","dependencies_parsed_at":"2024-08-03T01:39:09.001Z","dependency_job_id":null,"html_url":"https://github.com/ahrefs/melange-react-intl","commit_stats":null,"previous_names":["ahrefs/melange-react-intl-ppx","ahrefs/bs-react-intl-ppx","ahrefs/melange-react-intl"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahrefs%2Fmelange-react-intl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahrefs%2Fmelange-react-intl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahrefs%2Fmelange-react-intl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ahrefs%2Fmelange-react-intl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ahrefs","download_url":"https://codeload.github.com/ahrefs/melange-react-intl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247866127,"owners_count":21009238,"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-08-03T01:03:14.133Z","updated_at":"2026-02-12T04:21:03.379Z","avatar_url":"https://github.com/ahrefs.png","language":"Reason","funding_links":[],"categories":["Reason"],"sub_categories":[],"readme":"# melange-react-intl\n\nThe [react-intl](https://formatjs.io/docs/react-intl/) bindings for\n[Melange](https://melange.re/) and a\n[preprocessor](https://ocaml.org/docs/metaprogramming) that eases the creation\nof translated messages.\n\n## Installation\n\nInstall the [opam](https://opam.ocaml.org/) package manager, and then run:\n\n```shell\nopam pin add melange-react-intl.dev git+https://github.com/ahrefs/melange-react-intl.git#master\n```\n\n## Overview\n\nThe package consists of two parts:\n- The bindings to the `react-intl` JavaScript library.\n- The PPX, which allows you to create `ReactIntl.messages` records without\n  specifying `id`, significantly reducing the amount of boilerplate code and\n  simplifying the translation process.\n\n### Examples\n\nThis ReasonML code:\n\n```reason\nlet message: ReactIntl.message = [%intl \"I am a message\"];\n```\n\nwill be compiled to JavaScript as:\n\n```javascript\nvar message = {\n  id: \"168c9a2987fad481c5882847ac102aaf\",\n  defaultMessage: \"I am a message\"\n};\n```\n\nThe PPX also supports messages with a description:\n\n```reason\nlet withDescription: ReactIntl.message = [%intl {msg: \"blabla\", desc: \"I am a description\"}];\n```\n\n## Usage with the bindings\n\n```reason\n[@react.component]\nlet make = () =\u003e {\n  let intl = ReactIntl.useIntl();\n  // Helper functions\n  let l = message =\u003e intl-\u003eReactIntl.Intl.formatMessage(message);\n\n  \u003c\u003e\n    \u003ch1\u003e[%intl \"Some header\"]-\u003el-\u003eReact.string\u003c/h1\u003e\n    \u003cp\u003e[%intl \"Some body\"]-\u003el-\u003eReact.string\u003c/p\u003e\n  \u003c/\u003e\n}\n```\n\nYou can define your own `FormattedMessage` component, which accepts a\n`ReactIntl.message` instead of `id` and `defaultMessage`:\n\n```reason\n/// FormattedMessage.re\n[@react.component]\nlet make = (~item: ReactIntl.message, ~values: Js.t({..})) =\u003e\n  \u003cReactIntl.FormattedMessage id={item.id} defaultMessage={item.defaultMessage} values /\u003e;\n```\n\n## Draft phrases\n\nIf you want to make the\n[extractor](https://github.com/cca-io/rescript-react-intl-extractor) ignore some\nphrases, you can use `intl_draft`, `intl_draft.s`, or `intl_draft.el`\nextensions. This is helpful if you don't want some draft phrases (likely to\nchange soon) to be sent to translators.\n\n## Advanced usage\n\nThere is an option to generate a localized string straight from the PPX (without\nexplicit helper functions usage). This option could be helpful if you don't need\nto change the page language without page reloading.\n\n- Support for the `intl.s` annotation:\n\n```reason\nlet message: string = [%intl.s \"I am a message\"]; // type string\n```\n\nConverts to ⬇️\n\n```reason\nlet message: string = {id: \"168c9a2987fad481c5882847ac102aaf\", defaultMessage: \"I am a message\"}-\u003eReactIntPpxAdaptor.Message.to_s;\n```\n\n- Support for the `intl.el` annotation:\n\n```reason\nlet element: React.element = [%intl.el \"I am a message\"];\n```\n\nConverts to ⬇️\n\n```reason\nlet element: React.element = {id: \"168c9a2987fad481c5882847ac102aaf\", defaultMessage: \"I am a message\"}-\u003eReactIntPpxAdaptor.Message.to_s-\u003eReact.string;\n```\n\n- Support for variables, plural forms, and [rich text\n  formatting](https://formatjs.io/docs/react-intl/components/#rich-text-formatting)\n  in payload. In this case, the PPX will return a function instead of\n  `ReactIntl.message`:\n\n```reason\nlet element: React.element = [%intl.el \"I am a message with {variable}\"];\n```\n\nConverts to ⬇️\n\n```reason\nlet element: React.element =\n  (values: {. \"variable\": React.element}) =\u003e {id: \"168c9a2987fad481c5kgmcntg5k3dsd5\", defaultMessage: \"I am a message with {variable}\"}-\u003eReactIntPpxAdaptor.Message.format_to_s(_, values)-\u003eReact.string;\n```\n\nTo use these features, you have to define `ReactIntlPpxAdaptor` in your app (see\nthe `test` folder for details).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahrefs%2Fmelange-react-intl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fahrefs%2Fmelange-react-intl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fahrefs%2Fmelange-react-intl/lists"}