{"id":16750936,"url":"https://github.com/dvinciguerra/middleman-importmap","last_synced_at":"2025-10-20T11:50:52.502Z","repository":{"id":40448844,"uuid":"466272118","full_name":"dvinciguerra/middleman-importmap","owner":"dvinciguerra","description":"Importmap extension port for Middleman","archived":false,"fork":false,"pushed_at":"2024-05-10T12:56:15.000Z","size":45,"stargazers_count":4,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-07T23:18:07.662Z","etag":null,"topics":["frontend","importmaps","middleman","middleman-extension","ruby","rubygem"],"latest_commit_sha":null,"homepage":"https://rubygems.org/gems/middleman-importmap","language":"Ruby","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/dvinciguerra.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2022-03-04T21:13:45.000Z","updated_at":"2024-12-25T15:58:12.000Z","dependencies_parsed_at":"2025-02-11T08:30:56.419Z","dependency_job_id":null,"html_url":"https://github.com/dvinciguerra/middleman-importmap","commit_stats":{"total_commits":12,"total_committers":2,"mean_commits":6.0,"dds":0.08333333333333337,"last_synced_commit":"63758e14aeec7a546feea738e0a7b216bbb79dac"},"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/dvinciguerra/middleman-importmap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvinciguerra%2Fmiddleman-importmap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvinciguerra%2Fmiddleman-importmap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvinciguerra%2Fmiddleman-importmap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvinciguerra%2Fmiddleman-importmap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dvinciguerra","download_url":"https://codeload.github.com/dvinciguerra/middleman-importmap/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dvinciguerra%2Fmiddleman-importmap/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280087870,"owners_count":26269717,"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","status":"online","status_checked_at":"2025-10-20T02:00:06.978Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["frontend","importmaps","middleman","middleman-extension","ruby","rubygem"],"created_at":"2024-10-13T02:42:39.974Z","updated_at":"2025-10-20T11:50:52.467Z","avatar_url":"https://github.com/dvinciguerra.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# middleman-importmap\n\n[![Maintainability](https://api.codeclimate.com/v1/badges/aab4c3c09d920639f962/maintainability)](https://codeclimate.com/github/dvinciguerra/middleman-importmap/maintainability)\n\nAn Importmap extension for Middleman.\n\n\n## Install\n\n**Add gem to `Gemfile`**\n\n`gem 'middleman-importmap'`\n\n\n## Usage\n\n#### Activate extension in `config.rb`**\n\n```ruby\nactivate :importmap\n```\n\n#### Create the `importmap.yml` file at middleman root path\n\n```shell\n$ cd middleman_project \u0026\u0026 touch importmap.yml\n```\n\n#### Add importmaps to file (example)\n\n```yaml\nimports:\n  \"@hotwired/stimulus\": https://unpkg.com/@hotwired/stimulus/dist/stimulus.js\n```\n\nThe importmap.yml file keep the same structure of importmap in HTML\n\n\n#### Replace default javascript tag by importmap\n\n```ruby\n\u003c!doctype html\u003e\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"utf-8\"\u003e\n    \u003cmeta http-equiv=\"x-ua-compatible\" content=\"ie=edge\"\u003e\n    \u003cmeta name=\"viewport\"\n          content=\"width=device-width, initial-scale=1, shrink-to-fit=no\"\u003e\n    \u003c!-- Use the title from a page's frontmatter if it has one --\u003e\n    \u003ctitle\u003e\u003c%= current_page.data.title || \"Middleman\" %\u003e\u003c/title\u003e\n    \u003c%= stylesheet_link_tag \"site\" %\u003e\n    \u003c%= javascript_importmap_tags %\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003c%= yield %\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n#### Customize options if necessary\n\n##### in `config.rb`:\n\n```ruby\nactivate :importmap do |option|\n  option.entrypoint = \"site\" # js entrypoint's filename without extension\n  option.importmap = \"importmap.yml\" # importmap's filename with extension (yaml or json)\n  option.use_shim = true # or false\n  option.shim_src = \"path/to/shim\" # defaults to hardcoded js cdn\nend\n```\n\n##### or by specifying arguments in template helpers:\n\nThis will override options in config.rb\n\n```ruby\n\u003c%= javascript_importmap_tags(\"main\", importmap: \"importmap.json\", shim: false) %\u003e\n\n# or customize one by one:\n\u003c%= javascript_importmap_shim_tag(shim_src: \"another/path\") %\u003e\n\u003c%= javascript_inline_importmap_tag(\"importmap.json\", shim: true) %\u003e\n\u003c%= javascript_inline_module_tag(\"main\", shim: true) %\u003e\n\n# See source code for methods implementation\n```\n\n## Examples\n- [Creating an app using Stimulus JS](#creating-an-app-using-stimulus-js)\n- [Creating an app using React and React Router](#creating-an-app-using-react-and-react-router)\n\n\n### Creating an app using Stimulus JS\n\n#### Add the following code to `/source/javascripts/site.js`\n\n```javascript\nimport { Application } from \"@hotwired/stimulus\"\n\nimport HelloController from \"./controllers/hello_controller.js\"\n\nwindow.Stimulus = Application.start()\nStimulus.register(\"hello\", HelloController)\n```\n\n#### Create `controllers` directory\n\n```shell\n$ mkdir -p source/javascripts/controllers\n```\n\n#### Now add HelloController at `controllers/hello_controller.js`\n\n```javascript\nimport { Controller } from \"@hotwired/stimulus\"\n\nexport default class extends Controller {\n  connect() {\n    console.log(\"Hello, Stimulus!\", this.element)\n  }\n\n  greet() {\n    console.log(\"Clicked Greet Button\")\n  }\n}\n```\n\n#### One last and important thing is add element binding at `index.html.erb`\n\n```ruby\n---\ntitle: Welcome to Middleman\n---\n\n\u003ch1\u003e\n  Middleman is Running\n\u003c/h1\u003e\n\n\u003cdiv data-controller=\"hello\"\u003e\n  \u003cinput type=\"text\"\u003e\n  \u003cbutton data-action=\"click-\u003ehello#greet\"\u003eGreet\u003c/button\u003e\n\u003c/div\u003e\n\n\u003c%= link_to(\n  \"Read Documentation\",\n  \"https://middlemanapp.com/basics/templating_language/\",\n  target: \"_blank\"\n) %\u003e\n```\n\nIf all things are OK, than start middleman server using command `bundle exec middleman server` and open your browser devtools to see the messages.\n\n### Creating an app using React and React Router\n\nThis example is based on [DHH's Youtube video presenting rails-importmap gem using React and htm](https://www.youtube.com/watch?v=k73LKxim6tw).\n\n#### Change `importmap.yml` file to be like this\n\n```yaml\n---\nimports:\n  \"htm\": \"https://ga.jspm.io/npm:htm@3.1.1/dist/htm.module.js\"\n  \"react\": \"https://ga.jspm.io/npm:react@18.2.0/index.js\"\n  \"react-dom\": \"https://ga.jspm.io/npm:react-dom@18.2.0/index.js\"\n  \"react-router-dom\": \"https://ga.jspm.io/npm:react-router-dom@6.21.1/dist/main.js\"\n  \"htm_create_element\": \"/javascripts/htm_create_element.js\"\n\nscopes:\n  \"https://ga.jspm.io/\":\n    \"@remix-run/router\": \"https://ga.jspm.io/npm:@remix-run/router@1.14.1/dist/router.js\"\n    \"react-router\": \"https://ga.jspm.io/npm:react-router@6.21.1/dist/main.js\"\n    \"scheduler\": \"https://ga.jspm.io/npm:scheduler@0.23.0/index.js\"\n```\n\n#### Create `source/javascripts/htm_create_element.js` file\n\nThis file is necessary to use htm with React in an environment that doesn't have build process of JSX files.\n\n```javascript\nimport { createElement } from 'react'\nimport htm from 'htm'\n\nexport const h = htm.bind(createElement)\n```\n\n#### Create `components` and `pages` directories\n\n```shell\nmkdir -p source/javascripts/components \u0026\u0026 mkdir -p source/javascripts/pages \n```\n\n#### Create `components/Page.js` file\n\nCreating this file to avoid code duplication of components and demonstrate how to use composition in this environment.\n\n```javascript\nimport { h } from \"htm_create_element\"\n\nconst Footer = () =\u003e h`\n  \u003cfooter class=\"footer mt-auto py-3 bg-body-tertiary\"\u003e\n    \u003cdiv class=\"container\"\u003e\n      \u003cspan class=\"text-body-secondary\"\u003e\n        Build by \u003ca href=\"https://github.com/dvinciguerra\"\u003edvinciguerra\u003c//\u003e using \u003ca href=\"https://github.com/dvinciguerra/middleman-importmap\"\u003emiddleman-importmap\u003c//\u003e.\n      \u003c/span\u003e\n    \u003c/div\u003e\n  \u003c/footer\u003e\n`\n\nconst Container = ({ children }) =\u003e h`\n  \u003cmain class=\"flex-shrink-0\"\u003e\n    \u003cdiv class=\"container\"\u003e\n      ${children}\n    \u003c/div\u003e\n  \u003c/main\u003e\n\n  \u003c${Footer} /\u003e\n`\n\nconst Title = ({ children }) =\u003e h`\n  \u003ch1 class=\"mt-5\"\u003e${children}\u003c/h1\u003e\n`\n\nconst Lead = ({ children }) =\u003e h`\n  \u003cp class=\"lead\"\u003e${children}\u003c/p\u003e\n`\n\nexport default {\n  Container,\n  Title,\n  Lead\n}\n```\n\n\n#### Create `pages/Home.js` file\n\nNow, let's create the Home page using the components created above and react-router-dom `Link` component.\n\n\n```javascript\nimport { h } from \"htm_create_element\"\nimport { Link } from \"react-router-dom\"\n\nimport Page from \"../components/Page.js\"\n \nexport default () =\u003e h`\n  \u003c${Page.Container}\u003e\n    \u003c${Page.Title}\u003eMiddleman Importmap React\u003c//\u003e\n    \u003c${Page.Lead}\u003e\n      This is a simple page created using Middleman-importmap and React to demonstrate how it is possible to build\n      frontends in Middleman using importmap without any build.\n    \u003c//\u003e\n\n    \u003chr class=\"my-4\" /\u003e\n    \n    \u003cp\u003e\n      \u003c${Link}\n        to=\"/getting-started\"\n        class=\"btn btn-dark btn-lg\"\n        role=\"button\"\n      \u003e\n        Getting Started\n      \u003c//\u003e\n      \u003ca\n        href=\"https://github.com/dvinciguerra/middleman-importmap\"\n        class=\"btn btn-secondary btn-lg ms-1\"\n        role=\"button\"\n        target=\"_new\"\n      \u003e\n        GitHub\n      \u003c//\u003e\n    \u003c/p\u003e\n  \u003c//\u003e\n`\n```\n\n#### Create `pages/About.js` file\n\nCreating just another page to demonstrate how to use react-router-dom `Link` behaviour.\n\n```javascript\nimport { h } from \"htm_create_element\"\nimport { Link } from \"react-router-dom\"\n\nimport Page from \"../components/Page.js\"\n \nexport default () =\u003e h`\n  \u003c${Page.Container}\u003e\n    \u003c${Page.Title}\u003eAbout\u003c//\u003e\n    \u003c${Page.Lead}\u003e\n      This is a simple About page\n    \u003c//\u003e\n\n    \u003chr class=\"my-4\" /\u003e\n    \n    \u003cp\u003e\n      \u003c${Link}\n        to=\"/\"\n        class=\"btn btn-dark btn-lg\"\n        role=\"button\"\n      \u003e\n        Back\n      \u003c//\u003e\n    \u003c/p\u003e\n  \u003c//\u003e\n```\n\n#### Create `components/App.js` file\n\nCreating a component to wrap all pages and use react-router-dom `RouterProvider` component.\n\n```javascript\nimport { createBrowserRouter, RouterProvider } from 'react-router-dom'\nimport { h } from 'htm_create_element'\n\nimport Home from \"../pages/Home.js\"\nimport About from \"../pages/About.js\"\n\nconst router = createBrowserRouter([\n  { path: '/', element: h`\u003c${Home} /\u003e`  },\n  { path: '/about', element: h`\u003c${About} /\u003e` }\n])\n\nexport default () =\u003e h`\u003c${RouterProvider} router=${router} /\u003e`\n```\n\n#### Add the following code to `site.js`\n\n```javascript\nimport { render } from 'react-dom'\nimport { h } from 'htm_create_element'\n\nimport App from \"./components/App.js\"\n\nconst root = document.getElementById('root')\nrender(h`\u003c${App} /\u003e`, root)\n```\n\n#### Add the following code to `source/index.html.erb`\n\n```ruby\n---\ntitle: Welcome to Middleman\n---\n\n\u003cdiv id=\"root\"\u003e\u003c/div\u003e\n\n```\n\nIf all things are OK, than start middleman server using command `bundle exec middleman server`, open your browser and\naccess [http://127.0.0.1:4567/](http://127.0.0.1:4567/).\n\n\n## See more\n\n- [Importmap polyfill at guybedford/es-module-shims](https://github.com/guybedford/es-module-shims)\n- [Can I Use about Import Maps browser support](https://caniuse.com/import-maps)\n- [W3C Import Maps Spec](https://wicg.github.io/import-maps/)\n- [The helper tags are inspired by rails/importmap-rails gem](https://github.com/rails/importmap-rails)\n\n## License\n\nSee `./LICENSE` file for more details.\n\n## Author\n\nDaniel Vinciguerra\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdvinciguerra%2Fmiddleman-importmap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdvinciguerra%2Fmiddleman-importmap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdvinciguerra%2Fmiddleman-importmap/lists"}