Export a React Components HTML,CSS & JS via an NextJS API - javascript

i try to export an react components HTML, CSS, JS to implement it in another webpage.
Our System
NextJS (a header component with scss modules)
Spryker PHP based Webshop
How we style right now
import styles from "./Header.module.scss"
and then use it like this:
<div className={styles.hamburgerInner} />
sometimes we also have hardcoded classes like:
<div className={`col-auto order-3 ${styles.sbHeaderInfoIcons}`}>
inside the scss we also have variables:
background-color: $white;
which we import inside the Header.module.scss like this:
#import "src/styles/settings";
inside the settings we also have more imports where the variables and stuff are:
/**
* Settings
* -----------------------------------------
* Globally used functions, Mixins, Variables
*/
#import "functions/respond-to";
#import "functions/z-index";
#import "mixins/placeholder";
#import "mixins/pseudo";
#import "mixins/read-more";
#import "mixins/transition";
#import "mixins/typography";
#import "mixins/icon-map";
#import "mixins/rem";
#import "mixins/spacer";
#import "variables/breakpoints";
#import "variables/colors";
#import "variables/bootstrap";
#import "helper/spacing";
#import "helper/is-loading";
#import "helper/overlay";
Our Problem we want to solve
we now want to use components from system 1 in system 2 to not have to write the header components in both languages everytime we have changes here.
Problems we are facing while trying to find a solution
we cant render react directly inside spryker, because it is not serverside rendered and we have to keep SEO in mind here.
the only solution we came up with is to find a way to just get the HTML, CSS & JS from react to then just implement it there and "paste" the code. we would achieve it while using the api functionality from nextjs, so that system 2 can just call this api to get the contents
do you guys know of a solution for this, especially if we use css modules here?
What we already tryed
we already tryed to use reacts "renderToString" method but here we dont get the css because of the modules, only the html and also there is no way to get the logic of the component (the JS part).
rendering react directly in spryker is not possible because it got rendered in the client and we need SSR here because we have to keep SEO in mind. that also eliminates an iframe solution.

Related

React automatically importing all the CSS

So I'm doing a React App, Where the css files remains on src/dist/css, where src is located in the same local of App.js, the thing is I just want to import one single CSS file, but when I'm going to see every css file were automatically imported somehow.
I want to prevent this, because it's conflicting with the normal css screen.
These are the only things I'm Importing. ( IMAGE )
But All of these are being imported, I don't know if is something with React or the Server.. ( IMAGE )
EDIT: I figured out its because of React Router, Who is importing all the CSS to the App.JS, Still don't know how to prevent this.
There is no way to prevent this. Alternatives that you can look at are:
use BEM naming to have no conflicts all over the code.
use module.css, CSS module is a simple thing that can help you resolve the conflict without changing much of the CSS you have written.
i recommend you using styled-components or module.css. and tailwind also.

Set sass variable value in Angular 7

I have been working with angular for the last few weeks, and now I have a requirement to dynamically style a public site. The site admin set various color codes as well as a logo image from admin in a database. These will be reflected when the Public Site opens.
As I am from an asp.net background, previously what I would do is on master page load, take values from the DB and write them into a .less file, and let java-script library take care of it. It's simple there.
But for my current situation, I am using sass, and I am not able find a way to write variables into a .scss file.
I just learn a new thing APP_INITIALIZER from here ,but ultimately this post not showing how to write in the .scss file.
I am actually thinking this with my asp.net knowledge,but may be I am wrong ,or there are another way of implementation.
I want a simple solution ,what we do in asp.net I want to achieve this in same way.
Take variable value from DB via api,when application loading for first time.
Write values in SASS variable file .
After that SASS will take care of this and we get result as expected .
Please give some suggestion or example ,to start with .
Thanks.
As other answers explained, it is not possible to set SASS variables and process that on the client, as SASS is converted to plain CSS at build time and when app is running or in APP_INITIALIZER browser can process only CSS.
I see two options to achieve what you want.
Generally, you would have some base css for the app, and then you need to load the additional css based on admin settings. What needs to be considered from css point of view is that all css specificity in additional css should be greater than base css, because otherwise it won't override the base. That requires basic css knowledge so I won't go into details.
Method 1
Generate your additional css on server request. Load it when app is started from server URL. Reload it by js when admin change any settings.
Define backend endpoint at address /additional.css (or it could be similar to /api/theme/custom-css) which will generate css out of database. For example you have background=red in db, then the endpoint should return
body {background-color: red;}
Add <link id="additionalCss" rel="stylesheet" type="text/css" href="additional.css" /> in <head> of index.html. And that will be enough to make it work.
To reload you can use different methods, but I believe this should work
document.getElementById('additionalCss').href = document.getElementById('additionalCss').href;
This will make new request to the server, server will execute DB -> css and return the updated css, which will be applied to the browser.
And if you want to be cool (or need to support big and complex themes) scss can be used. Backend should generate scss variable definitions out of database, then should use some server-side app to compile scss -> css, and then serve compiled css back to the client. But this will be overkill if additional css is simple enough.
One important consideration of this method is browser caching, because content behind additional.css is dynamic, but browser may cache it, not call the backend and serve outdated version.
Method 2
If you don't want or can't mess with the backend. Load settings from DB by some API endpoint in json, then generate css code on the client and apply it.
Use HttpClient to get settings JSON and generate css as string out of it. For example server returns
{
"background": "red"
}
then you convert this to string as
cssCode = 'body {background-color: red}';
Use
let additionalCssStyle = document.getElementById('additionalCss');
if (! additionalCssStyle) {
additionalCssStyle = document.createElement("style");
additionalCssStyle.id = 'additionalCss';
document.head.appendChild(additionalCssStyle);
}
additionalCssStyle.innerText = cssCode;
To reload - save changed to backend, then repeat 1. and 2.
While #Cold Cerberus has suggested a good approach and is right about maintaining style related things at front-end, i am suggesting some ways for this.
As you said you want various colour combination,you can use Conditional CSS of SASS.
body[theme="theme1"] {
// theme 1 css
}
body[them="theme2"] {
// theme 2 css
}
You can use sass theme map along with conditional css.
Just update your attribute and theme will be applied automatically.
themeChange() {
const dom = document.querySelector('body');
dom.theme = theme1; // change theme here
}
If you are very particular about some element style which should be updated from back-end (like colour code) you can use ng-style along with theme approach.
<some-element [ngStyle]="{'font-style': styleExp}">...</some-element>
You have to use smart combination of above in order to fulfill your requirement.
First of all, in ASP .NET, it might be not bad to have a db hold CSS rules and other static assets. This is because it is a Server Side Rendering framework, so it kinda makes sense.
On the other hand, in Angular, it is client side (with the exception of Angular Universal, but you'll still have to expect working in similar approaches). Even with translations (i18n or custom), in Angular world, it is most likely stored on the front end (i18n .json files) and not from the back (db or so).
So you'll have to go and have your theme's stored in a certain manner you prefer and make your way to switching between them dynamically with Angular. You can of course store the keys/variables for the styles/themes but your actual CSS code is still stored on .css files.
Try to see this simple example from CSS vars in use while dynamically setting app theme (Angular). This is only just one way and there are lots of ways to do this and you might have to look for your personal preference.
UPDATE:
There might be erroneous implications of my answer above, but I'll leave it as is and just share one experience I had that is related to this topic.
I have worked on a webapp where the user can customize his theme via settings, likewise, The CSS rules aren't stored on DB, but the color values to be set on sass variables are. There was a special script where CSS scripts will be compiled (was returned on demand which made it a bit slow but a splash screen just saves your day, not AOT compiled) along with the custom values, which I don't have any idea how it was done. The same with translations, I also recently worked on a project where translations are from db, but there's a script to run for every release/deployment that generates and updates the .json files in the assets/i18n folder.
I don't think that what you want will be possible to do... Angular processes the SASS files during application build and writes all the common results into a plain old css file. The component-specific stuff will get generated as javascript that, in turn, will apply your styling at run time.
Hence all the SASS variables you need to set up have to be present at compile time.
What you can do, though, is to pre-define your setup in Angular components and then toggle it based on an input (from your DB or wherever else), like so:
// your.component.ts
#Component({
// ... component stuff
styles: ['h1.option1 {color: red;}', 'h1.option2 {color: blue;}'],
template: `
<h1 *ngIf="optionSelection$ | async as option; else noOption"
[class.option1]="option == 1"
[class.option2]="option == 2">
Hey there, I'm styled!
</h1>
<ng-template #noOption>
<h1>No option received</h1>
</ng-template>
`
})
export class YourComponent {
optionSelection$: Observable<number>;
constructor(yourService: YourService){
this.optionSelection$ = yourService.getYourOption().pipe(startWith(null));
}
}
Hope this helps a little :-)
Since sass is a pre compiled css. we cannot dynamically change the theme without generating a seperate theme.css. This is where JSS comes to play. JSS is a javascript based style inject mechanism, where css are directly injected into the files you are using it.
react-angular-material uses it extensively, where we can pass color variables dynamically to change theme of the application.
for instance this guy has made it with angular.
Docs:
jss-angular,
jss
links: jss-with-angular
It is not possible in that way but rather than using the sass variable, you use the value of the sass variable. It may be any value.
Why? because sass is compiled during packaging and in the end, it would still generate plane CSS.
An example of a framework making use of this optional style processor is angular.
In your case I would recommend looking into dynamic themeing within angular as what you require definitely needs JavaScript. Look into the guide on medium given by one of the contributors.
https://stackoverflow.com/a/54559350/3070499

Is there a way to use a working HTML page as an Angular 5/6 component?

We are undergoing an project in Angular 5/6 where we get prebuilt HTML pages, that use jQuery, gridstack.js and CSS for UI, that we'll implement as components. Assuming it's not possible to rewrite all the jQuery and JS code in Angular, is there any way to run the jQuery code provided in the tag directly in Angular?
I have already tried importing jQuery as:
import $ from 'jQuery';
Here is a sample of the code:
<script type="text/javascript">
$(function () {
$('.grid-stack').gridstack({
width: 12
});
$(".accordion-toggle").click(function () {
$(this).toggleClass("activu");
$(".accordion-toggle").not(this).removeClass("activu");
})
var options = {
float: true
};
$('.grid-stack').gridstack(options);
</script>
It is possible and could be a good intermediate step on a migration path.
I am working on a project right now where we have a JQuery-based app. It has a lot of CSS and HTML code inside the JS code to handle state changes and change content and styling accordingly. It is relatively messy.
We took a number of steps of migrating to Angular, with the first being what you are describing. It definitely already helped gain an overview of the code base and structure the code in a much more maintainable way than it was before.
I took the HTML and broke it down into Angular components. For this step, we just left the JQuery code in the main AppComponent TS file. You can simply use JQuery in Angular TS files with a declare const $: any;.
I broke down the the JQuery code and migrated everything that was template related (e.g. changing parts of the DOM tree based on events/state) into the Angular HTML files.
I took the one large CSS file and moved the CSS rules to the individual components.
I went through the entire remaining JQuery code and piece by piece migrated it to proper Angular code.
It proved to be a viable strategy. We were first considering re-writing the entire project, but like this we always had a running version, could continuously run UI tests against it and piece by piece migrate.
All of that is to say: I would not see a JQuery/Angular mix as a final solution, but it can be a good migration strategy.
You can use jQuery in your angular project. Normally jQuery based DOM manipulation is not the standard way for angular but in some cases we have to jQuery plugins for certain features.
Steps:
Import jQuery script in your index.html
<script src="assets/js/jquery.min.js"></script>
Import your plugin css/js in .angular-cli.json inside styles and scripts arrays
Inside the component where you want to use it , declare jQuery.
declare var $ : any;
Use in directly in your component. If plugin needs to be initialised , you can do it inside ngOnInit

How to make edits work on reacts component library css files?

I am using some component libraries for a project with react such as antd, material-ui etc. I need to modify some components css. For example, I looked up in the directory of antd and located the css files under node_modules\antd\dist. There are few files along with antd.css and antd.min.css there is also a file named antd.less.
My question is which file do I make the change to css? Help would be very much appreciated.
Hard to say but probably the antd.less.
I would strongly recommend to overwrite the css in a localcss file instead of modifying node_modules though. Will be more convenient to maintain. It will become a pain in production or if you want to update your modules. Considered bad practice.
And if you do want to edit it directly in the module, clone the module into your rep. Dont leave it in node_modules, for the same reasons.
Overriding Less variables (alternative way)#
Override variables via less definition files.
Create a standalone less file like the one below, and import it in your project.
#import "~antd/dist/antd.less"; // import official less entry file
#import "your-theme-file.less"; // override variables here
Default Variables
https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less

How to use commercial themes with meteor.js

I'm a newbie who's trying to build a meteor app, and I was looking to cut some time by using a commercial theme. Let's take this as an example:
http://themeforest.net/item/metronic-responsive-admin-dashboard-template/4021469?WT.ac=category_item&WT.seg_1=category_item&WT.z_author=keenthemes
I have two options:
1) Use the html to create meteor templates, using spacebars tags, etc.
But how would I implement the theme javascript? doesnt it comes in conflict with meteor?
2) Use angular.js, as the theme is provided in angular.js format other than plain html. But wouldnt this create conflicts? is this a better approach?
In general, what is the easiest and best way to use commercial themes with meteor?
I bought similar themes on wrapbootstrap. I think it is the same problem here. (for Angular theme I do not know, as it would be trickier I think to integrate it with bootstrap)
Generally with such themes, you have a lot of 3rd-part JS libraries. You have to get them.
First option, you find a similar packages on atmosphere and you can add it. (A lot of jQuery library are simply wrapped as packages).
Second option, there is no such package (you can make and add them, and it would help the community :)). You can import them on the page you need with a package like wait-on-lib
You can import the libraries where you need them only. But I think the first option is cleaner.
And you will probably have some custom.js for each different page you have in your template, you have to transfer this logic when you render a template. For example the custom.js for the index file in your template will be transformed in :
A template name index where you can put the HTML and
Template.index.rendered = function(){
/* your custom js */
}
For the CSS you can simply copy past the files in client/css (for example) the files will be loaded.
I do not know if I have been very clear, but I managed to integrate such themes in meteor project. And do not forget to remove unnecessary files, for example when you add the bootstrap package, you can remove the bootstrap css and js files integreted to your template.
P.S : You may have to search/remplace path in the css and js files from the templates to load some images for example. Put all such files (as images) in your public folder, where you want, but do not forget to rewrite the path in your css and js files.
For example if you bougth a template where they have folder like :
folder_css
folder_image
...
the path are written this way :
/* css files */
background-image: url(../folder_image/myimage.png);
But in a meteor project, all files in public folder are at the root of the project, so you can rewrite your path, with for example something like this :
/* css files */
background-image: url(img/myimage.png);
Rewrite path in JS files also and I think it should work.

Categories