FAQ about migrating the sealcode's website to JDD

Here’s what you need to know to get started on tasks from Migration of our website to JDD.

Historical context

The old website is using a in-house static page generator. As our CMS is maturing, it’s time to dogfood our own solution and make it a showcase of what can be achieved with our stack! Also, we plan to add an English version of the website, and migrating to a more dynamic infrastructure is going to be very helpful.

The most labour-intensive part of the migration is going to be migrating the old “html.js” components from old website to our new shiny JDD components.

html.js components are similar in function to JDD components - they are functions that take some arguments and return a string of HTML. The differences are:

  • html.js components do not expose the information on the types of the arguments they accept. Because of that it’s not possible to automatically build an interface for editing them, as it is the case with JDD components;
  • html.js components do not use JSX syntax.

Migrating the old components to JDD must involve converting them to JSX syntax and creating argument specifications in a way that enables the users of JDD editor to customize the content and look of the components.

The new components should be created in https://hub.sealcode.org/source/www-2024/repository/master/ using the JDD tooling: Adding a new JDD component to a Sealious app

1. Setup the old repository

The old repository is available at https://hub.sealcode.org/source/company-www/. Clone it and use it for reference. Components are in the /pages-src/components directory. They include a html.js file that describes the html, and a .scss file that includes the styles. It’s ok (and recommended!) to copy-paste them to their JDD counterpart for a quick start.

2. Run fractal

To see the components from the old website live, you can run:

npm install
make build
make docs

And then visit localhost:3000 in your browser. You should see something like this:

CSS Gotchas


In the old website, we’re using the rem unit a lot. In hindsight, this caused more confusion than it’s worth. During migration of the components, replace all rem-sized elements with px sizes. You can use the conversion of 1rem = 24px.

If you see such a beast:

height: px-to-rem(17px);

just use height: 17px;

CSS @imports

The old website used SCSS import statements to manage CSS dependencies.

In the new website, all css files are just concatenated into one big file and served to the front-end, so there’s no need to do any @imports. If the component you’re migrating relies on some other css file in a different directory, move that file over from the old codebase to src/global-styles/<filename>.css, if it’s not already there. See also the related discussion at Creating a global style file

CSS Nesting

We moved away from SCSS to simplify the bulid stack of the frontend resources. CSS now supports much of what made us use SCSS in the first place, so many pieces of the code can be just copied and pasted to the new website.

One thing that SCSS did and CSS cannot do, however, is concatenation-based nested selectors. We did use those heavily in the old website, so this is an important note.

In SCSS, you can make a nested set of selectors like this:

.button {
   &--red {
       color: red;

   &--red {
       color: green;

The above compiles to

.button--green {
   color: green;

.button--red {
   color: red;

This is something currently not possible to do in CSS. We can use & in nested CSS selectors, but we cannot use it co construct new classes like in the example above.

You can either unwrap the styles by hand, or use an online converter like Online SCSS Compiler - BeautifyTools.com

Note that the above converter removes all nesting, making the selectors kind of repetitive and less readable in some cases. Proceed with caution :pray:

Media queries

The old website was created before wonders such as Container Queries existed. Now that we have the luxury of using container queries, we use them everywhere. JDD Components will not scale, if they are style using media queries. Thus all media queries have to be changed to container queries. Usually changing

@media (max-width: 950px) {


@container (max-width: 950px) {

will be enough.

That’s it for now. I will be updating this post as more questions arise. I’d like to direct my thanks to @anastasy_pat, @danvei, @nijatbabakhanov, @xanderazuaje for pioneering work on the migration and a lot of patience that was necessary to start treading that path :muscle:


When migrating components with images, there are two important things to note:

Raster images

For bitmap images, like jpg, we need to use the jdd_context.render_image function. It results in an <img> tag wrapped with <picture>. Some styles regarding the layout of the img element might thus become misaligned. Make sure that all styles that were applied to the img element are also applied to the picture element.

Vector images

When dealing with customizable SVG images, for now just assume that they are links provided to the component with a ShortText argument and use them directly as values for the src attribute in HTML.

You can put some testing images in ./public directory - they will be served automatically as static files. Just don’t put them in ,/public/dist, as they will be .gitignored