Playing around with Rails 7 and I don't understand why my custom CSS is not working.
I built new rails app with flag for Bootstrap, which is working fine (CSS and JS, tested with bootstrap modal). These are my default config files:
application.js
// Entry point for the build script in your package.json
import "#hotwired/turbo-rails"
import "./controllers"
import * as bootstrap from "bootstrap"
application.bootstrap.scss
#import 'bootstrap/scss/bootstrap';
package.json
{
"name": "app",
"private": "true",
"dependencies": {
"#hotwired/stimulus": "^3.0.1",
"#hotwired/turbo-rails": "^7.1.0",
"#popperjs/core": "^2.11.2",
"bootstrap": "^5.1.3",
"esbuild": "^0.14.23",
"jquery": "^3.6.0",
"popper.js": "^1.16.1",
"sass": "^1.49.9",
"stimulus": "^3.0.1"
},
"scripts": {
"build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds",
"build:css": "sass ./app/assets/stylesheets/application.bootstrap.scss ./app/assets/builds/application.css --no-source-map --load-path=node_modules"
}
}
And I can built CSS in /builds/application.css
Now I want to add custom CSS. This is my process:
Added new file stylesheets/custom.css, with css:
.my-class {
color: #fff;
background-color: #00eb00;
}
Add import to application.bootstrap.scss
#import "custom";
yarn run build:css
And now I can see .my-class in builds/application.css
But when I try to use id in HTML, no CSS is added. Why? Should I place it somewhere else?
EDIT: I got it running, but only when I run manually rails assets:precompile and then bin/dev.
Why do I need to precompile every time I change something?
In a fresh rails 7 app (with css=bootstrap), here's what I did to get custom css styles:
Uncomment gem 'sass-rails in Gemfile, then bundle install (more info on that here)
Create a new css file in app/assets/stylesheets and name it example.css.scss
Add this line to app/assets/config/manifest.js:
//= link example.css
Wherever you need access to those styles, include this tag
<%= stylesheet_link_tag "example", "data-turbo-track": "reload" %>
Start your server with bin/dev instead of rails server
Everything should work (a nice test is to include this in your example.css.scss file and H1s should turn green)
h1 {
color: green;
}
Resource
Very helpful video here
I just encountered this problem and noticed both JavaScript and CSS are not recompiled after changes.
If you have gem jsbundling-rails included in your gemfile, check out https://github.com/rails/jsbundling-rails for more details and how-tos.
Run yarn run build:css to recompile the CSS assets.
I prefer using ./bin/dev to start my local server and monitor both JavaScript and CSS updates.
It worked for me if I added
//= link custom.css
to app/assets/config/manifest.js
And I didn't add #import "custom"; to application.bootstrap.scss
Related
I am running into a strange issue where everything is working as expected except select2. I am having Rails 6.0.0 app and installed select2 via yarn add select2.
Then i added it to application.js file. File looks like below.
#app/javascripts/packs/application.js
require("#rails/ujs").start()
require("turbolinks").start()
require("#rails/activestorage").start()
require("channels")
require('datatables.net')
require('datatables.net-dt')
require('datatables.net-bs4')
require('select2')
import "bootstrap"
import 'popper.js/dist/popper.js';
import $ from 'jquery';
global.$ = jQuery;
import "chart.js"
import 'select2'; // globally assign select2 fn to $ element
import 'select2/dist/css/select2.css'; // optional if you have css loader
document.addEventListener("turbolinks:load", () => {
setTimeout(function() {
$('.success, .alert').fadeOut();
}, 10000);
})
Right now it looks like this
select2 dropdown box
When I go to Source tab in chrome developer tools, it shows only select2/dist/js folder under node_modules. I have tried precompiling and clobbering the assets but not working. The whole this is running fine in my local, only causing issue in production server.
Edit:
My production.rb
https://gist.github.com/rajanhcah/3ee13925b0ae305a6fe2c64013ab6534
If you're including CSS in app/javascripts/packs/application.js, make sure that app/views/layouts/application.html.erb is also using the stylesheet_pack_tag (see the "Usage" section in the webpacker doc).
Otherwise, if you have stylesheet_link_tag, you can use the classical app/assets/stylesheets/application.css.
# app/assets/stylesheets/application.scss
#import 'select2/dist/css/select2';
I am trying to use the cookieconsent package with webpacker in ruby on rails 5.1.4.
My package.json is
{
"dependencies": {
"#rails/webpacker": "3.5",
"bootstrap": "^4.1.1",
"cookieconsent": "^3.0.6"
},
"devDependencies": {
"webpack-dev-server": "2.11.2"
I have added a cookieconsent.scss in app/javascript with the following content
#import 'cookieconsent/build/cookieconsent.min.css'
I am running webpack-dev-server which compiles successfully, including processing the cookieconsent.scss file viz
Child extract-text-webpack-plugin node_modules/extract-text-webpack-plugin/dist node_modules/css-loader/index.js??ref--2-2!node_modules/postcss-loader/lib/index.js??ref--2-3!node_modules/sass-loader/lib/loader.js??ref--2-4!app/javascript/cookieconsent.scss:
[0] ./node_modules/css-loader??ref--2-2!./node_modules/postcss-loader/lib??ref--2-3!./node_modules/sass-loader/lib/loader.js??ref--2-4!./app/javascript/cookieconsent.scss 10.7 kB {0} [built]
[1] ./node_modules/css-loader/lib/css-base.js 2.26 kB {0} [built]
In the head of the html page being loaded I have
<%= stylesheet_pack_tag 'cookieconsent' %>
When I load the page, I get the following error message at this stylesheet_pack_tag line
Webpacker::Manifest::MissingEntryError - Webpacker can't find cookieconsent.css in /Users/Chris/Sites/golf_mentor/public/packs/manifest.json. Possible causes:
1. You want to set webpacker.yml value of compile to true for your environment
unless you are using the `webpack -w` or the webpack-dev-server.
2. webpack has not yet re-run to reflect updates.
3. You have misconfigured Webpacker's config/webpacker.yml file.
4. Your webpack configuration is not creating a manifest.
Your manifest contains:
{
"application.css": "/packs/application-4aa426d9718df1187dbf816f0f19f567.css",
"application.css.map": "/packs/application-4aa426d9718df1187dbf816f0f19f567.css.map",
"application.js": "/packs/application-157f642ed5e88a31abbb.js",
"application.js.map": "/packs/application-157f642ed5e88a31abbb.js.map",
"counter.js": "/packs/counter-9d94c8ee2c39e62e654d.js",
"counter.js.map": "/packs/counter-9d94c8ee2c39e62e654d.js.map"
}
:
app/views/pages/temp.html.erb:3:in `block in _app_views_pages_temp_html_erb__4517159242875817520_70136616900600'
app/views/pages/temp.html.erb:1:in `_app_views_pages_temp_html_erb__4517159242875817520_70136616900600'
How do I fix this?
I ended up solving this by installing cookieconsent using sprockets.
However this post, https://rubyyagi.com/how-to-use-bootstrap-and-jquery-in-rails-6-with-webpacker/, although it does not deal specifically with cookieconsent does provide more information on how to install third party css files using webpacker.
I'm working on a Rails app that uses Semantic UI as its frontend framework.
I'm using Rails 5.
I followed the instructions on this site (https://github.com/Semantic-Org/Semantic-UI-Rails-LESS) to include the gems needed for Semantic to work on Rails.
In my html.erb file (the left portion of the photo), I've used some Semantic UI buttons, just to test out if Semantic loads.
I believe it loaded, but I'm getting a bunch of errors in my console (+ it is saying on the top right that the Style sheet could not be loaded).
What seems to be the problem?
EDIT
I was able remove the 'Style sheet could not be loaded' error by lowering my 'sprockets' gem version to 3.6.3, instead of 3.7.1. (I'm not sure if this is a safe way of doing it, though. There were warning of deprecated methods in the sprockets, so people were suggesting to use version 3.6.3 instead.) However, the other errors in the console log still remained.
EDIT 2
The 'Style sheet could not be loaded' error still remained.
EDIT 3
I switched to the sass version of Semantic UI, and the "Style sheet could not be loaded" error is now gone! But, the console still had the "error in parsing values" error. I still don't know what is causing this. Any thoughts/fixes to this?
Since Rails 5.1 you can use yarn to integrate Semantic UI with your app. Here's how I've done it. Process is not perfect (you still have to run rails tmp:clear after changing your theme files), but it gives you advantage of using the latest semantic-ui package and not being dependent on gem updates.
Using
Ruby: 2.5.1
Rails: 5.2.0
Create a new rails app
$ rails new semantic_integration
$ cd semantic_integration
$ bundle install
create semantic.json in your app directory
{
"base": "app/assets/semantic/semantic-ui",
"paths": {
"source": {
"config" : "src/theme.config",
"definitions" : "src/definitions/",
"site" : "src/site/",
"themes" : "src/themes/"
},
"output": {
"packaged" : "dist/",
"uncompressed" : "dist/components/",
"compressed" : "dist/components/",
"themes" : "dist/themes/"
},
"clean" : "dist/"
},
"permission": false,
"autoInstall": true,
"rtl": false,
"version": "2.3.1"
}
run $ yarn add semantic-ui.
This will install semantic-ui in app/assets/semantic
Add followin lines to config/initializers/assets.rb
# semantic-ui assets
Rails.application.config.assets.paths << Rails.root.join('app', 'assets', 'semantic')
Rails.application.config.assets.paths << Rails.root.join('app', 'assets', 'semantic', 'semantic-ui', 'src', 'themes', 'default')
Add Semantic UI css
// app/assets/stylesheets/application.css
*= require 'semantic-ui/src/semantic'
Add Semantic UI js
// app/assets/javascripts/application.js
// after turbolinks
//= require jquery
//= require semantic-ui/dist/semantic
Add init.js and require it in app/assets/javascripts/application.js
window.App || (window.App = {});
App.init = function() {
// here goes Semantic UI component initialisation
// i.e.
$('.ui.menu .ui.dropdown').dropdown({
on: 'hover'
});
$('.ui.menu a.item')
.on('click', function() {
$(this)
.addClass('active')
.siblings()
.removeClass('active');
});
};
$(document).on('turbolinks:load', function () {
App.init();
});
In you Gemfile add:
gem 'therubyracer'
gem 'less-rails'
and run bundle install
Now you app should be able to compile Semantic UI less files.
If you're getting error:
expected ')' got 'o'
go to app/assets/semantic/semantic-ui/src/theme.less
and remove (optional) keywords on #import statements
Icon font
go to: app/assets/semantic/semantic-ui/src/site/globals/site.variables
and add:
/* Fonts */
#fontPath : "assets/fonts";
then go to: app/assets/semantic/semantic-ui/src/site/elements/icon.variables
and add:
/*******************************
Icon
*******************************/
/*--------------
Font Files
---------------*/
#fontName: 'icons';
#src:
font-url("#{fontPath}/#{fontName}.eot?#iefix") format('embedded-opentype'),
font-url("#{fontPath}/#{fontName}.woff2") format('woff2'),
font-url("#{fontPath}/#{fontName}.woff") format('woff'),
font-url("#{fontPath}/#{fontName}.ttf") format('truetype'),
font-url("#{fontPath}/#{fontName}.svg#icons") format('svg')
;
#fallbackSRC: font-url("#{fontPath}/#{fontName}.eot");
/*--------------
Optional Files
---------------*/
/* Outline Icons */
#importOutlineIcons: true;
#outlineFontName: 'outline-icons';
#outlineSrc:
font-url("#{fontPath}/#{outlineFontName}.eot?#iefix") format('embedded-opentype'),
font-url("#{fontPath}/#{outlineFontName}.woff2") format('woff2'),
font-url("#{fontPath}/#{outlineFontName}.woff") format('woff'),
font-url("#{fontPath}/#{outlineFontName}.ttf") format('truetype'),
font-url("#{fontPath}/#{outlineFontName}.svg#icons") format('svg')
;
#outlineFallbackSRC: font-url("#{fontPath}/#{outlineFontName}.eot");
/* Brand Icons */
#importBrandIcons: true;
#brandFontName: 'brand-icons';
#brandSrc:
font-url("#{fontPath}/#{brandFontName}.eot?#iefix") format('embedded-opentype'),
font-url("#{fontPath}/#{brandFontName}.woff2") format('woff2'),
font-url("#{fontPath}/#{brandFontName}.woff") format('woff'),
font-url("#{fontPath}/#{brandFontName}.ttf") format('truetype'),
font-url("#{fontPath}/#{brandFontName}.svg#icons") format('svg')
;
#brandFallbackSRC: font-url("#{fontPath}/#{brandFontName}.eot");
Important!
For some reason less-rails gem monitors changes to
app/assets/semantic/semantic-ui/src/semantic.less but not any other
files in app/assets/semantic/semantic-ui/src folder. After changin
*.variables, *.overrides, or *.config files run rails tmp:clear or manually delete tmp/cache/assets folder.
Demo App
https://github.com/ziinfo/semantic_integration.git
any idea how to deal with that ? I mean jquery-ui seems not to be amd and I don't know how to manage that , any idea ?
jquery-ui-dist and jquery-ui-bundle do not seem to be maintained by the jquery-ui team. After jquery-ui v1.12 Its possible to use the official jquery-ui package from npm with webpack.
Update jquery-ui to 1.12 by updating package.json and npm install.
Then you can require each widget like this.
require("jquery-ui/ui/widgets/autocomplete");
require("jquery-ui/ui/widgets/draggable");
If you have used require("jquery-ui") before you need to replace it with separate imports for each widget. I think the new way is better because it will bundle only the code for the widget we need to use.
See documentation on using the 1.12 official npm package.
For some reason jquery-ui didn't play nice with webpack. I had to require jquery-ui-bundle instead.
npm i -S jquery-ui-bundle
and then require it after jquery e.g.
require('jquery');
require('jquery-ui-bundle');
youre in luck I did this just that yesterday, it's rather easy.
npm install --save jquery jquery-ui
Make sure that you have jquery aliased to resolve with the plugin in the webpack.config.js
...
plugins: [
new webpack.ProvidePlugin({
"$":"jquery",
"jQuery":"jquery",
"window.jQuery":"jquery"
}),
...
Then include two aliases in the webpack.config.js
The node_modules folder
The jquery-ui folder
``````
resolve : {
alias: {
// bind version of jquery-ui
"jquery-ui": "jquery-ui/jquery-ui.js",
// bind to modules;
modules: path.join(__dirname, "node_modules"),
Make sure that jquery gets loaded first in your app startup file.
var $ = require("jquery"),
require("jquery-ui");
If you need to use a theme configure the css-loader and the file-loader. Don't forget to npm install those loaders.
module: {
loaders: [
{ test: /\.css$/, loader: "style!css" },
{ test: /\.(jpe?g|png|gif)$/i, loader:"file" },
And use in your app startup file.
require("modules/jquery-ui/themes/black-tie/jquery-ui.css");
require("modules/jquery-ui/themes/black-tie/jquery-ui.theme.css");
webpack-jquery-ui
webpack-jquery-ui
- use this plugin, e.g. if you use Rails 5, run
yarn add webpack-jquery-ui
When jQuery UI plugin starts, it checks if jquery provided, so
Add this code to your webpacker configuration file (shared.js - if you use it with Rails 5)
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery'",
"window.$": "jquery"
})
]
Add these lines into your app code.
require('webpack-jquery-ui');
require('webpack-jquery-ui/css');
to fix ActionController::InvalidAuthenticityToken in jquery.ajax
You have to pass an authenticity_token parameter with all your PUT, POST and DELETE requests.
To do that you can usually fetch it from the header with $('[name="csrf-token"]')[0].content
So your request would look something like:
var that = this;
$.ajax({
url: navigator_item.url,
data: { authenticity_token: $('[name="csrf-token"]')[0].content},
method: 'DELETE',
success: function(res) {
...
}
});
I include jQuery into my application in another way
Instead of using:
plugins: [
new webpack.ProvidePlugin({...
You should add 'jquery': 'jquery/src/jquery' to aliases in the webpack config file:
module.exports = {
resolve: {
alias: {
'jquery': 'jquery/src/jquery'
}
}
It will provide module name 'jquery'. jQuery UI checks this name on init.
Then in you app.js file you write:
import $ from 'jquery'
import 'webpack-jquery-ui/css'
import 'webpack-jquery-ui/sortable' // if you need only sortable widget.
window.jQuery = $;
window.$ = $; // lazy fix if you want to use jQuery in your inline scripts.
The accepted answer doesn't work for me as the jQuery-ui package on NPM isn't pre-built and therefore doesn't contain jquery-ui.js; the package will either need built before use or all the widgets included/used individually.
Quickest way I got the whole package working was by first downloading the distributable version:
npm install jquery-ui-dist --save
I needed to add an alias for jquery-ui-dist to avoid a 'Cannot find module' error (using just require('jquery-ui-dist') won't work, because the .js filename is different), by adding this to webpack.config.js:
resolve: {
alias: {
'jquery-ui': 'jquery-ui-dist/jquery-ui.js'
}
},
Finally, you can use this in the .js file where the modules are loaded:
var jQuery = require('jquery');
require('jquery-ui');
Alternatively, you can avoid having to require the scripts when loading the modules, and having to declare jQuery as a variable, by using ProvidePlugin in your webpack.config.js:
plugins: [
new webpack.ProvidePlugin({
'jQuery': 'jquery',
'$': 'jquery',
'global.jQuery': 'jquery'
})
],
The steps that worked for me (in a Rails 5.1.6 project) aren't identical to any of the above:
Install jquery and jquery-ui: yarn add jquery and yarn add jquery-ui
Add the following to the webpack config (i.e. in /config/webpack/environment.js) to globally set $ and jquery and jQuery:
environment.plugins.prepend(
'Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
jquery: 'jquery'
})
)
Require whichever individual jquery-ui package(s) you want, at the top of your pack (e.g at the top of /javascript/packs/application.js:
require("jquery-ui/ui/widgets/sortable")
Then you can call, for example, $('.selector').sortable() anywhere in your pack.
add jquery in your node_modules using;
npm install --save jquery jquery-ui
and add externals in your webpack.config.js like;
...
externals: {
// require("jquery") is external and available
// on the global var jQuery
"jquery": "jQuery",
"jquery-ui": "jquery-ui/jquery-ui.js",
}
it worked for me
You should import all of these and check which ones you really need.
require('jquery-ui/ui/core.js');
require('jquery-ui/ui/data.js');
require('jquery-ui/ui/form.js');
require('jquery-ui/ui/form-reset-mixin.js');
require('jquery-ui/ui/focusable.js');
require('jquery-ui/ui/disable-selection.js');
require('jquery-ui/ui/plugin.js');
require('jquery-ui/ui/labels.js');
require('jquery-ui/ui/position.js');
require('jquery-ui/ui/scroll-parent.js');
require('jquery-ui/ui/tabbable.js');
require('jquery-ui/ui/unique-id.js');
require('jquery-ui/ui/widget.js');
require('jquery-ui/ui/widgets/accordion.js');
require('jquery-ui/ui/widgets/autocomplete.js');
require('jquery-ui/ui/widgets/button.js');
require('jquery-ui/ui/widgets/checkboxradio.js');
require('jquery-ui/ui/widgets/controlgroup.js');
require('jquery-ui/ui/widgets/datepicker.js');
require('jquery-ui/ui/widgets/dialog.js');
require('jquery-ui/ui/widgets/draggable.js');
require('jquery-ui/ui/widgets/droppable.js');
require('jquery-ui/ui/widgets/menu.js');
require('jquery-ui/ui/widgets/mouse.js');
require('jquery-ui/ui/widgets/progressbar.js');
require('jquery-ui/ui/widgets/resizable.js');
require('jquery-ui/ui/widgets/selectable.js');
require('jquery-ui/ui/widgets/selectmenu.js');
require('jquery-ui/ui/widgets/slider.js');
require('jquery-ui/ui/widgets/sortable.js');
require('jquery-ui/ui/widgets/spinner.js');
require('jquery-ui/ui/widgets/tabs.js');
require('jquery-ui/ui/widgets/tooltip.js');
require('jquery-ui/ui/effect.js');
require('jquery-ui/ui/effects/effect-blind.js');
require('jquery-ui/ui/effects/effect-bounce.js');
require('jquery-ui/ui/effects/effect-clip.js');
require('jquery-ui/ui/effects/effect-drop.js');
require('jquery-ui/ui/effects/effect-explode.js');
require('jquery-ui/ui/effects/effect-fade.js');
require('jquery-ui/ui/effects/effect-fold.js');
require('jquery-ui/ui/effects/effect-highlight.js');
require('jquery-ui/ui/effects/effect-puff.js');
require('jquery-ui/ui/effects/effect-pulsate.js');
require('jquery-ui/ui/effects/effect-scale.js');
require('jquery-ui/ui/effects/effect-shake.js');
require('jquery-ui/ui/effects/effect-size.js');
require('jquery-ui/ui/effects/effect-slide.js');
require('jquery-ui/ui/effects/effect-transfer.js');
require('jquery-ui/ui/vendor/jquery-color/jquery.color.js');
I'm struggling to properly install and configure Semantic-UI using bower in my Rails 4 app.
Until now, here's what I've done:
Gemfile:
gem "less-rails"
gem "therubyracer"
.bowerrc file:
{
"directory": "vendor/assets/components"
}
bower.json:
{
"name": "app",
"version": "0.0.0",
"homepage": "myapp.com",
"private": true,
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"vendor/assets/components",
"test",
"tests"
],
"dependencies": {
"semantic-ui": "~1.12.2"
}
}
After bower install, semantic UI gets properly pulled into my /vendor/assets/components folder
Now, I'd like to take advantage of semantic's theming properties, without of course editing what's currently loaded by bower.
I've added the following in semantic.css.less, itself being required in application.css
#import "semantic-ui/src/semantic";
The issue now: semantic lib seems to be properly fetched in the proper folder, as I get the following error:
'site//globals/site.variables' wasn't found
Ok I understand that.
But how do I use custom configuration files with the default assets installed by bower without touching these ?
How can I properly create the required configuration files (theme.config / site.variables / site.overrides), out of my /vendor/assets/components folder, and still properly assigning the SASS variables required for the lib to compile ?
I would take a gander at less-rails-semantic-ui, this is what I ended up going for my new rails project. It properly adds all the override files in vendor/assets!
If you are using less source files without npm (which includes an installer), you will need to manually create theme.config from theme.config.example and site/ from _site/ this is to avoid upstream changes affecting your local ui.
https://github.com/Semantic-Org/Semantic-UI/tree/master/src#config-files
PS: from the owner answer, source:
https://github.com/Semantic-Org/Semantic-UI/issues/2239