"Enhance your web app with Emotion.js and Preact SSR, complete with

In my preact SSR application, I have utilized Emotion JS 10 for styling purposes.

My goal was to incorporate RTL support into the app. To achieve this, I implemented createEmotion and createEmotionServer, leveraging the resulting renderStylesToString to render the app.

However, in the process of creating createEmotion, I encountered a challenge where the RTL styles were being consistently applied, whereas I needed them to be applied on a per-request basis.

I searched for a method to instruct Emotion to apply and retrieve the RTL styles for every request, but I couldn't find a straightforward solution tailored for Preact.

One potential solution would involve serving distinct webpack builds for RTL, but this would introduce unnecessary overhead.

EDIT 1: for those interested in implementing something similar, here is my approach

Both on the client side and during server-side rendering:

import stylisRTL from 'stylis-rtl';

import createEmotion from 'create-emotion';

const {
  cx: cxRTL,
  injectGlobal: injectGlobalRTL,
  css: cssRTL,
  cache: cacheRTL,
  keyframes: keyframesRTL
} = createEmotion({
  key: 'c',
  stylisPlugins: [stylisRTL]
});
const {
  cx: cxLTR,
  injectGlobal: injectGlobalLTR,
  css: cssLTR,
  cache: cacheLTR,
  keyframes: keyframesLTR
} = createEmotion({
  key: 'c',
  stylisPlugins: []
});

const runForBoth = (rtlFn, ltrFn) => (...args) => {
//this would be ur store sent in html to check whether it is in rtl or ltr mode
  const isRTL = typeof window !== 'undefined' && window.__PRELOADED_STATE__.shell.RTL;
  let result;
  if (__BROWSER__) {
    if (isRTL) {
      result = rtlFn(...args);
    } else {
      result = ltrFn(...args);
    }
  } else {
    result = ltrFn(...args);
    rtlFn(...args);
  }

  return result;
};

export const cx = runForBoth(cxRTL, cxLTR);
export const injectGlobal = runForBoth(injectGlobalRTL, injectGlobalLTR);
export const css = runForBoth(cssRTL, cssLTR);
export const keyframes = runForBoth(keyframesRTL, keyframesLTR);

export const cacheEmotionLTR = cacheLTR;
export const cacheEmotionRTL = cacheRTL;

And for server-side rendering:


const { renderStylesToString: renderStylesToStringLTR } = createEmotionServer(cacheEmotionLTR);
const { renderStylesToString: renderStylesToStringRTL } = createEmotionServer(cacheEmotionRTL);

I establish two caches and based on request headers, I determine which renderStylesToString to utilize.

There's a minor concern with runForBoth technically not being accurate. However, it currently functions as intended.

I opted not to alter the way the css function is imported, allowing me to seamlessly integrate these custom Emotion imports by aliasing them in webpack configurations

Answer №1

To customize this on a per request basis, it's recommended to set up 2 instances of emotion (one with the plugin and one without). To ensure each request uses the correct instance, consider storing the emotion in a context and accessing it from there instead of using an import statement.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to create a linear flow when chaining promises?

I am facing an issue with my flow, where I am utilizing promises to handle the process. Here is the scenario: The User clicks a button to retrieve their current position using Ionic geolocation, which returns the latitude and longitude. Next, I aim to dec ...

Mysterious dual invocation of setState function in React

My component is designed to display a list of todos like: const todosData = [ { id: 1, text: "Take out the trash", completed: true }, { id: 2, text: "Grocery shopping", completed: false }, ]; ...

JavaScript code for extracting information from a table

After analyzing the table below: <table id="cart-subtotals" cellspacing="0" class="shop_table shop_table_responsive"> <tbody> <tr class="cart-subtotal"> <th>Subtotal</th> <td data-title="Subtotal"><span ...

Encountering undefined JavaScript functions when called from HTML

I had most of these functions working perfectly, but after restarting my program, I'm now encountering issues with undefined functions in Chrome. I can't pinpoint the exact problem, and even though I've checked through Eclipse, I still can&a ...

The Vue router is unable to access the store state

My Vue application is utilizing vue-router and vuex. I acquire an authentication token from my API, store it in localStorage, and then push it to the store. However, when the page refreshes, the app is unable to retrieve the token from localStorage and the ...

The positioning of CSS arrows using the "top" attribute is not relative to the top of the page when using absolute values

I am currently working on positioning the arrow in the screenshot using TypeScript calculations. However, I am facing an issue where the position is being determined based on the top of the black popup instead of the top of the screen. From the top of the ...

The addListener method in Google Maps iterates n times for a specific number of repetitions

When looking at the code below, the GetPropBasedOnRadius(); method loops for a certain number of times. I want to call that method only when the dragging event is completed. However, I am unsure how to do this. Any assistance on this matter would be great ...

NodeJS server connection delay

My server has an Express NodeJS instance installed. The API stops responding when it is overloaded, leading to the following response: POST /my/api/result - - ms - - I attempted the following in ./bin/www: server.on('connection', function(sock ...

Refresh tab controllers in Angular JS on every click event

Is there a way to refresh the tab controller every time a tab is clicked? Here's the current code: $scope.tabs = [ { id: 'tab1', title: 'tab1', icon: 'comments', templateUrl: 'tab1/tab1.tpl.html&ap ...

Is there a way to import content from a .json file in webpack5?

Currently, I am facing an issue with webpack5 where I am unable to import .json files. From my understanding, there should be no need to install a loader for importing json files. However, out of curiosity, I did install "json5-loader" and defined the foll ...

Executing a query with a `has many` relationship in MongoDB: Step-by-step guide

In my setup with Node, Express, and backbone, I am successfully retrieving records from MongoDB collections using simple queries. However, I am struggling to understand how to query more complex data, such as the one below: db.employees.aggregate( [ ...

Add a plugin to the website after the DOM has finished loading

Here is a code snippet that utilizes a jQuery plugin to apply scrollbars to a DOM element: <script type="text/javascript"> $(document).ready(function () { $(".pp-meta-content").customScrollbar(); }); </script> This code works ...

Ways to avoid extra function loads in JavaScript

I'm currently working on an instant search feature and have some code implemented: $(function() { var timer; $("#searchterm").on('keypress',function() { timer && clearTimeout(timer); timer = setTimeout(doStuff, 800); tim ...

The xslt code is failing to invoke the JavaScript function

I am currently utilizing xslt for the transformation of xml to html. Below is an example of an .xml file. <ImportOrganizationUtility-logging> <log-session module-name="ImportOrganizationUtility" end="17:54:06" start="17 ...

if a condition is not being properly assessed

Currently, I am working on a $.ajax call to retrieve data in JSON format. Within this JSON data, there is an element called "status." My code snippet checks if the value of `data.status` is equal to "success" and performs some actions accordingly. Despite ...

"Enhance Your Website's User Experience with jQuery Aut

One of the challenges I am facing involves an Ajax call that retrieves a JSON representation of data created using PHP's json_encode method: ["Montérégie","Montréal - North Shore","Montréal - South Shore"] These values are extracted from a &apos ...

"Unlocking the Power of mediaElementjs: Easy Steps to Accessing the Player Instance

I'm facing a small issue with the MediaElement.js player. To access the player instance, I usually use the following code (which works in HTML5 compatible browsers): // Retrieve player this.playerId = $('div#shotlist-player video').att ...

Canvas does not display any results when trying to integrate Shadertoy

While browsing through StackOverflow, I came across a post detailing how to transfer shader examples from ShaderToy into Three.js. You can find the post here. I followed the steps mentioned in the post and created this Plunker demo. The fragment shader co ...

"Utilizing a Handlebars Helper to Evaluate if Two Values (v1 and v2) are Equal, and Displaying Content from

To make the actual call, I require something along these lines: <script id="messagesTemplate" type="text/x-handlebars-template"> {{#each messages.messages}} {{#each to}} {{#ifCond username messages.sessionUserName}} <h1> ...

How can jQuery be used to determine if the number of checked checkboxes is a multiple of three?

Within the ul, I have li tags with checkboxes and I want to create a function that checks, when the submit button is pressed, if the number of checked checkboxes is not a multiple of 3. If it isn't, an alert should be displayed. How can I accomplish t ...