Wrapping a dynamic custom skin around a Next.js app in server-render phase - reactjs

I did look through the similar questions and found this one, but the answer there isn't, at least by itself, dynamic enough for my needs.
Similar to that question, I am attempting to put together a multi-tenant application with a different skin per property. However, the answer given in the above question assumes that the various skin resources can be hard-coded into the application. That would be fine if we were talking about 2 or 3 skins, but my application will need to support dozens at launch and probably tens of thousands in its lifetime (each property can create multiple skins for different campaigns).
I have an API where I can request the skin, which is currently a long string of HTML with a token embedded indicating where the application contents should be rendered into the skin (e.g. {{body}}).
One of the things I'll need to do is inject some <link> tags into the <Head> element to pull in some external CSS. If React.Fragment supports attributes (like __dangerouslySetInnerHTML), I haven't been able to figure out how. If it's possible, that might be one way.
I'll run into the same problem when I want to inject some pre-application and post-application content into the body of the page, too.
Since I want the skin to be rendered server-side on the first request and then be static until the tab is closed, it makes sense to do this in pages/_document.js. After that, I'm kind of lost for what to do next. Parsing the string that contains the skin content is easy enough, but how do I intermingle that raw HTML with React components?

Related

how to export react JS components to static html

are there any utilities or approaches to export regular react component into an email friendly static html?
for example i have a dashboard using react-table and would love it if there was a way to auto-magically translate that to static html i could insert into an email body.
i can think of a few approaches using a headless browser to render as pure html, but it would be awesome if there was a solution with more email friendly html
Because the layout of these gets fairly complex, it may also be advantageous to render page as image and insert that image into email body?
I only really know HTML Email, and basics of React - and SO is not great for recommendations of software type questions - so I'll just speak to the email side.
If you can get HTML, you need to consider a few things.
First, anything over two columns is likely to run out of space. You would need to consider a stackable column structure with repeated headers. That would require hiding the duplicated headers for desktop views, since the tables would be separate due to the way we do stacked columns in emails (as inline-blocks without media queries). See https://medium.com/#nathankeenmelb/bulletproof-responsive-datatables-in-html-emails-64248b9e18f5 for full details.
Second, only some approaches would work like that. Images then would be your go-to option. A nice output for table images would be:
<img src="https://via.placeholder.com/600x500" width="600" style="vertical-align:middle;width:100%;border:0">
The link goes to the image itself so you can zoom and move around easier, and get maximum realestate.
An alternative built on that idea would be to have a link from the image to landing page with full web capabilities. That would take longer to load, but may be well worth it.
Since that's probably the most viable, I'll explain these choices of attributes and styles:
Use the width attribute width="600" because that's what Outlook desktop uses
Use inline styles for those email clients that do not support <style> blocks
Vertical-align:middle (or display:block) removes the space underneath the image that some email clients add
width:100% makes it responsive to mobiles
border:0 ensures no border is shown because of the link
Third, datatables are so finicky and particular in HTML email. Each table is unique because they have different data in them that responds differently. In normal web design, you can just use a nice reset and get everything working without much thought. In HTML Email, everything needs to be inline, and supported, with fallbacks for those things that are unsupported. So even the core data often needs editing - e.g. if it has long URLs, emails or words you need to add a wrapping span with word-break CSS but also <wbr>s in the middle of it for some email clients to properly wrap.
Datatables don't often come up, and because of these considerations, it's hard to see how they could be automated easily - and hard to build a case for it financially.
On a related note, if you can show the information using card UI, that seems to me to be a much nicer, simpler, more accessible and easier to code solution than datatables. This is about taking the information and redesigning it into card blocks. I talk about that in detail here: https://medium.com/#nathankeenmelb/responsive-datatables-through-card-ui-design-for-email-aca6f3c395a2

react-engine vs other template engines

I was wondering to use paypal's React Engine (https://github.com/paypal/react-engine), but I have some doubts:
What are the benefits over other template engines like Handlebars?
Why upload .jsx files, and not (jsx precompiled/transformed) .js files? (This one should be faster because don't have to do deal with the transformation at the server).
I have been researching but I get confused.
Thanks
The main difference between react-engine and template engines is only when the browser enables the user to interact with the browser page. Nevertheless, it is important how machines have access to individual data.
Assuming we want to run a simple webpage. Just a scrolling and open text information. Using template engines, like Handlebars.js, typically, when the browser request hits to the server, it tries to figure it out how to respond and what to do. That said, the template engine may reference existing fetched data from files stored into a local and accessible source. Those are loading all the defined data regarding the site template file (i.e. head, meta, title, etc.), with a render of incomplete HTML string. This HTML is then sent back to the Browser and rendered.
The react-engine, on the same side it happens the use of the same rendering mechanism. However, instead of a template engine semantic, it uses JSX, or if we want, we can also use JavaScript. The JSX is, therefore, broader then template engines. A great article by Hajime Yamasaki Vukelic complies the separation of concerns from a different angle between JSX and HTML templates.
With template engines, you feed the library a string (usually but not
necessarily HTML), which is then converted into a piece of JavaScript
code which generates virtual DOM structures when executed. At design
time, templates are just strings, so we don’t have direct access to
the surrounding code. For instance, we can’t import helper functions,
or call methods. These things are only possible through abstractions
called directives (and possibly other names depending on where you are
coming from). Directives are the glue between the HTML and the
JavaScript.
So far so good, there is no relevant difference between both solutions. Links to next or previous simple webpage are just simple <a href="/webpage>Next</a> elements.
At the moment, when we decide to implement some interactions, react-engine will be the winner. While react-engine rendering does not require JavaScript to run on the client side, it will enable SEO over the search.
Template engines also have this SEO support, but with less impact. We can not run here all JavaScript to render HTML. Even libraries like jQuery require live access to the browser window object which cannot be mocked easily on the server side. So template engines become less productive.
In conclusion, template engines can do the same as react-engine rendering. Maybe not equally easy or equally fast but both tools are qualified. You can also read another great thread on this topic.

How would I repeat content on pages (and modify some) in DNN

I am trying to figure out how to place content across pages as well as modify only some of the "same" things.
For example, I have two services. Let's say I want to add a small box on the right panel. On the pages directly under the root of my site (Home, About Us, Contact Us), I want this box to contain generic information (We provide services for . . . ). On the pages related to service one (the service one page and sub-pages), I want that same box to contain pretty much the same text except changing it specific to service one (Our service one solution...). The same for service two and it's sub-pages (Our service two solution...).
To change content I think I'd be right to leave "Make a Copy" checked. However, I don't want this box to appear on every page, just one's that I choose (whether grouped or not; i.e. root pages, service one pages, service two pages).
How can I accomplish this? I'm working directly using the DNN 7.01 admin/host interface - I'm imagining I can accomplish this by creating separate .ascx files, but for this I think it defeats the purpose.
Thanks.
What you will want to do is use the "Add Existing Module" function to handle this.
For example for the content that you want to be the same, add it to the "main" page and setup the content. Then on the pages that need to have THAT version use "Add Existing Module" and add the module from the "main" page.
Then, when you have a variation that is to be shared across other pages, repeat this process.
DO NOT use the "Display On All Pages" option though as more than likely that will trash things!
I've not a lot of experience as Mitchel, and his answer seems the way to go. But as an alternative (when dealing with LOTS of modules with static content), I found using a template page with all the modules (and content within) helps to group things so that you can use that template for sub pages that have the same content. In other words, only the actual content pane for a sub page needs to be created because you are copying all the other "widgets" you have on your page.

Should we create custom pages for all objects?

I noticed that salesforce doesn't allow to override control function for all objects.
Say if you want to do something whenever objects get saved there is no way to attach the action
unless you create a custom page and include either standard controller or extension. Or if you want
to add the same meta-tag on all pages I run into this limitation. Is there better way to do this?
Generally - no. Roughly speaking if Salesforce doesn't allow you to do something it usually means there's pretty good hint you're doing in it wrong. I realize it sounds like I'm a fanboy but in reality - can you expand your question with concrete example why would you want to do something like that? For example governor limits are evil, annoying etc. - but they force you to write effective code that doesn't strain the database too much.
if you want to do something whenever objects get saved
That's what triggers are for. Ask yourself a question if the "action" you need to make should happen only from web UI or also when performed from API (mass data load, a smartphone application etc).
if you want to add the same meta-tag on all pages
You could maybe pull off similar result by adding a component to the sidebar. It won't cover all cases (like accessing Reports/Dashboards) but it's hard to say more without knowing what you're really after. Then again - custom VF page overrides won't help you when it comes to Reports either.
I wanted to add this as a comment, but was unable to.
Anyways, For the example that you mentioned in the comment, You can add that jQuery plugin in the Home page side bar component and activate the plugin only on those custom objects where you wnat to run this plugin. You might already know that we can deduce which object a record belongs to by looking at the 1st 3 letter of the record Id, using this logic, check if the record belongs to the custom object you want your plugin to act on and run the plugin.
But As eyescream has pointed out adding script in side bar has its own limitations: you cannot use the global variables , side bar components are not loaded on the reports and dashboard tabs etc.
-ಸಮಿರ್

What are your recommendations for reducing the number of resources (JavaScript and CSS) that DotNetNuke loads?

The home page for DotNetNuke 5.2 is around 252.6KB. It uses 15 JavaScripts and 8 CSS files. The number of resources DotNetNuke uses seems excessive to me. I am looking for best practices creating DotNetNuke skins that limit the JavaScript and CSS resources.
You can use the Unload CSS Skin Object to remove links to some of the CSS files loaded by the framework (like Default.css, portal.css & any module-specific CSS files). You can then move all of those styles into the skin (or portal stylesheet, whichever is your preference), so that there's only one stylesheet that gets loaded.
I don't know of any solutions for combining JavaScript resources or reducing the number of scripts that DNN requires.
From 6.1 onward, the Client Resource Management component is the solution for this. It automatically combines all your files, cleaning them up, removing comments, and minifying if desired.
http://www.dotnetnuke.com/Resources/Wiki/Page/Client-Resource-Management-API.aspx
It takes a little getting used to, but the control is quite nice. You can decide which order they'll go in, you can group the files in bunches if you don't want one big single file - maybe you want certain bunches of scripts together but not all.
One thing to remember is that when you're doing development (as noted by the comment below, which I've since edited this post), you should always use debug=true in the web.config, otherwise if you are using Resource Mgmt and change your source files, you'll constantly need to regenerate the combined files by going into Site Settings, Client Resource Management, and increment the version. It's kind of a protection to keep anything from altering your clients' browser caches without intent (that's the message box that pops up to let you know when you do it). I'm sure if you have a zillion users this might make a difference.
Part of that is just the dynamic nature of DNN - there are some good resources that R2i has published about combining javascript and CSS
One concrete suggestion is to combine all your skin and contianer css in one file and if you have full control of the site to combine the css from the modules you use into that same file.
I know with the addition of the Telerik controls there is some abilities to combine resource files
Another thing that helps is to combine graphics into a single file and use CSS (the sprite technique) to cut down number of files loaded and calls to the sever
Like it was stated above, it's the nature of the beast. Each module will have at least 1 css file included. You can check out PageBlaster from snapsis.com, I believe it will do what you are looking for.

Resources