{"resource":{"author":{"id":"h2so9H8jPMmgUKGghoNl","name":"Yomesh Gupta","username":"yomeshgupta"},"content":{"link":null,"difficulty":4,"domain":2,"type":1,"isInternal":true,"body":"Remix is the newest JavaScript framework in the developer community right now. It is a full-stack web framework that focuses on core web fundamentals to deliver a blazing-fast user experience. We will discuss how we can use SASS with Remix.\n\n## How does styling work in Remix?\n\n[Remix](https://remix.run/docs/en/v1/guides/styling \"Remix Styling Guide\") uses the good old way of adding a simple `<link rel=\"stylesheet\">` tag to the webpage for styling. If a route is active then stylesheet is added to the page. When a route is inactive then the stylesheet is removed. It is simple, effective, and helps in avoiding styling clashes.\n\nNow, for stylesheets, or any link, to show up on the page, we need to let Remix know about them. We can do so by exporting a `links` function that should return an array. Each entry in the array corresponds to a `link` tag in the head of the document.\n\n```js\n// login.js\nimport loginStyles from \"~/styles/login.css\";\n\nexport function links() {\n  return [\n    {\n      rel: \"stylesheet\",\n      href: loginStyles\n    }\n  ]\n}\n...\n```\n\n## Can we provide our SASS files as links?\n\nThe `href` for a stylesheet should link to a plain CSS file because that is what browsers understand! We can link our SASS files as long as we provide the generated plain CSS. Importing SASS file directly into a component or route simply won't work.\n\n## How to make it work?\n\nLet us say we want to style our `Login` page and we have our styling stored in the `login.scss` file.\n\nWe need to find a way to compile our SASS files and provide the generated css for Remix to process. In a normal webpack setup, we can simply use loaders like `sass-loader`, plugins like `MiniCssExtractPlugin`, and call it a day! The webpack will know how to process the asset and take care of everything.\n\nWith Remix, we need to manually process the sass files. We need a simple package to make it work.\n\n- [node-sass](https://www.npmjs.com/package/node-sass \"Node Sass npm package\") provides binding Node.js to LibSass (The C version of Sass).\n\n### Setting up\n\n1. Create a new remix app\n\n```bash\nnpx create-remix@latest\n# choose Remix App Server\ncd [whatever you named the project]\n```\n\nNow, our directory structure would look like the following\n\n```\nmy-remix-app\n├── app\n│   └── routes\n│   └── styles\n```\n\nThe `styles` folder will contain all the `.css` files.\n\n2. Create & add stylesheets to a `styles/` folder next to `app/`\n\n```bash\nmkdir styles\ncd styles\ntouch login.scss\n```\n\n```\nmy-remix-app\n├── app\n│   └── routes\n│   └── styles\n├── styles\n│   └── login.scss\n```\n\n3. Install the package\n\n```bash\nnpm i node-sass\n```\n\n4. Add scripts to `package.json` that will process the files in `styles/` and write them to `/app/styles/` where Remix modules can import them.\n\n```js\n{\n  \"scripts\": {\n    \"build:css\": \"node-sass ./styles -o ./app/styles --output-style compressed\",\n    \"dev:css\": \"npm run build:css && node-sass -rw ./styles -o ./app/styles\"\n  }\n}\n```\n\n5. Use it! During development, open a terminal tab and run the watch script\n\n```bash\nnpm run dev:css\n```\n\nThis will initially build all your scss files and then recursively watch all directories & files.\n\nWhen building for production, run\n\n```bash\nnpm run build:css\n```\n\nNow, styling in our `styles/login.scss`\n\n```css\n.wrapper {\n  background-color: red;\n  display: flex;\n\n  button {\n    color: white;\n  }\n}\n```\n\nwill be compiled to `app/styles/login.css`\n\n```css\n.wrapper {\n  background-color: red;\n  display: flex;\n}\n\n.wrapper button {\n  color: white;\n}\n```\n\nRemix modules can import it as any other css file!\n\n## Points to remember\n\n1. If you create a new scss file then you have to restart the watch process.\n2. You can run these processes together with something like [concurrently](https://www.npmjs.com/package/concurrently).\n\n<!-- Now, we can use `node-sass` to compile our sass files and make them available to Remix. -->\n\nIf you want to learn more useful and real-world Frontend related content then check out our [YouTube channel](https://www.youtube.com/watch?v=qMkUziVZvzs&list=PL4ruoTJ8LTT8250F2ZrYVmRO6o5gWZKpG) below.\n\n<iframe width=\"560\" height=\"315\" src=\"https://www.youtube.com/embed/qMkUziVZvzs\" title=\"YouTube video player\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen></iframe>\n","languages":[],"editorConfig":{}},"stats":{"views":33353,"used":0,"likes":0},"description":"","published":true,"isActive":true,"tags":["remix","js framework","dev tooling","sass","css","styling","frontend"],"slug":"setting-up-sass-with-remix-run---rid---lXDyMjDSdDZDXxNcJ2ep","isPremium":false,"categories":[],"requires":[],"_id":"61eeae76c596de5b12fea561","title":"Setting Up SASS With Remix Run","resourceId":"lXDyMjDSdDZDXxNcJ2ep","createdAt":1643032182296,"modifiedAt":1643270565545},"currentUser":null,"isOwner":false,"recommendations":{"questions":[{"_id":"62ac3a62d3473370ac366837","content":{"languages":["javascript","typescript"],"difficulty":1},"tags":["javascript","testing","jest","testing framework","frontend","javascript fundamentals","tooling","frontend fundamentals","codedamn","frontend masters","devtools tech","react testing library"],"slug":"implement-your-own-testing-library-or-frontend-problem-solving-or-javascript-interview-question---qid---hHNlFuWqXFomrjoJrj8Z","title":"Implement your own Testing Library | Frontend Problem Solving | JavaScript Interview Question","questionId":"hHNlFuWqXFomrjoJrj8Z"},{"_id":"694e30c490e8879697315d53","content":{"languages":["react","html"],"difficulty":1},"tags":["javascript","ui","ux","devtools tech","frontend interview coding challenge","frontend question","ui component","animation"],"slug":"interactive-voting-poll-component---qid---Dq50V3IUh3JsFhmxU4SL","title":"Interactive Voting Poll Component","questionId":"Dq50V3IUh3JsFhmxU4SL"},{"_id":"6290aeb7d3473370ac35f49e","content":{"languages":["javascript","typescript"],"difficulty":2},"tags":["javascript","array","loop","programming","async","parallel programming","requests","coding","devtools tech","frontend","codedamn","frontend masters","blog","tutorial","frontend interview question","advanced js"],"slug":"how-to-implement-custom-map-function-with-limit-on-number-of-operations-or-paytm-frontend-interview-question-or-javascript-interview-questions-or-frontend-problem-solving---qid---ZVNw2lUMguEZIsnvzjC1","title":"How to implement custom map function with limit on number of operations? | Paytm Frontend Interview Question | JavaScript Interview Questions | Frontend Problem Solving ","questionId":"ZVNw2lUMguEZIsnvzjC1"},{"_id":"5f3901df6d3cda64e470c3db","content":{"difficulty":4,"languages":"javascript"},"tags":["javascript","this concept","scoping","frontend","javascript fundamentals","js fundamentals","interview questions"],"slug":"explain-how-this-works-in-javascript---qid---A8Ri4jGfXJESFtKx0Dz7","title":"Explain how \"this\" works in JavaScript?","questionId":"A8Ri4jGfXJESFtKx0Dz7"},{"_id":"5eb25c583f4a621665113a2e","content":{"difficulty":1,"languages":"javascript"},"tags":["node.js","javascript","string","string manipulation","interview questions","frontend"],"title":"What would be the output? (String Reversal)","questionId":"ILCc690ZNZrXPXS8oOT0","slug":"what-would-be-the-output-string-reversal---qid---ILCc690ZNZrXPXS8oOT0"}],"resources":[{"_id":"639222ff937c6f54916670ee","content":{"difficulty":3,"domain":2,"type":2,"isInternal":false},"tags":["frontend","javascript","react","interview question","coding","programming","custom hooks","react hooks","ui","ux","blog","tech"],"slug":"how-to-create-useprevious-react-custom-hook-or-advanced-react-js-or-javascript-interview-question---rid---Dwblxb3EWYYxTG2vmwEp","title":"How to create usePrevious React Custom Hook? | Advanced React.js | JavaScript Interview Question","resourceId":"Dwblxb3EWYYxTG2vmwEp"},{"_id":"6963e277132ce4e954b04414","content":{"difficulty":4,"domain":2,"type":1,"isInternal":true,"languages":[]},"tags":["javascript","ui","ux","devtools tech","coding","frontend performance","browser rendering cycle"],"slug":"mastering-critical-rendering-path---rid---VyhOczhtA0Ds1kp2s4TN","title":"Mastering Critical Rendering Path","resourceId":"VyhOczhtA0Ds1kp2s4TN"},{"_id":"69a52acc92f33c7d8a9f6107","content":{"difficulty":4,"domain":1,"type":2,"isInternal":false,"languages":[]},"tags":["javascript","ui","ux","devtools tech","tutorial","rendering","coding"],"slug":"how-react-ssr-actually-works-without-frameworks---rid---8decG2azJUycVwuG2WQE","title":"How React SSR Actually Works (Without Frameworks)","resourceId":"8decG2azJUycVwuG2WQE"},{"_id":"5f1dd80bcbec5f7ffc0c2faf","content":{"difficulty":2,"domain":3,"type":1,"isInternal":true},"tags":["node.js","javascript","bots","automation","puppeteer","browser automation","ui testing","web scraping","linkedin scraping","devtools","ui"],"slug":"tips-to-improve-browser-automation-bots---rid---UVxuatGCbZwSMoQtQtaS","title":"Tips to improve Browser Automation Bots","resourceId":"UVxuatGCbZwSMoQtQtaS"},{"_id":"662b53824079503047f86f7f","content":{"difficulty":1,"domain":1,"type":1,"isInternal":true,"languages":[]},"tags":["javascript","frontend","ui","ux","devtools tech","coding","debounce","flipkart","react","tutorial","interviews","visa"],"slug":"what-is-debouncing-explain-with-examples---rid---bn9IQcem9rnLw7rT6gqk","title":"What is Debouncing? Explain with examples","resourceId":"bn9IQcem9rnLw7rT6gqk"}]}}