Skip to main content

How can I bundle external css files with block?


Hi there,

This question is for the Airtable team.

I see that you are using browserify to bundle the block code, would love to also be able to bundle external css files with the block, instead of loading them asynchronously using loadCSSFromURLAsync (which also makes development and deployment more complex).

There are quite a few browserify transformation packages that can make that happen, but I haven’t been able to make them work so far, when trying to control browserify transformations from the package.json file.

Here are the packages I tried / found so far:

brfs - doesn’t work with es6 modules
brfs-babel - doesn’t do the transform, for some reason, even when i add {"browserify": {"transform": ["brfs-babel"] } } to package.json
browserify-css - haven’t tried it yet

Using loadCSSFromString and providing the css itself isn’t the correct way since then I can’t easily edit it as css in a code editor or share it between blocks.

Would love to know how Airtable would recommend doing this.

Thanks,
Ronen

11 replies

Richard_Sinn

Hi Ronen,

Thank you for the feedback, especially around your experiences with the browserify plugins/packages. More robust CSS support for Blocks is something we are definitely considering and hoping to improve in the future.

Thanks,
Richard


  • Inspiring
  • 25 replies
  • April 19, 2020

Here’s how I write CSS locally during development.

First of all, I write SCSS and not CSS directly.

  1. I write styles.scss. I compile it to “css” using SCSS compiler in watch mode
    sass --watch frontend/styles/main.scss frontend/styles/styles.css

Now main.scss gets converted to styles.css.

  1. Then I convert styles.css to a styles.js which is the whole css file converted to a string by surrounding with template literals.

So the styles.js looks like:

export default `
    .classname: {
        border: 1px solid red;
    }
    ... rest of your styles css here
`;
  1. This styles.js can be imported in your Custom block and passed to loadCSSFromString
import stylesString from './styles/styles.js';;
import { loadCSSFromString } from '@airtable/blocks/ui';
loadCSSFromString(stylesString);

And this allows me to update my stylesheets with hot reloading.

I wrote about this here - How to import CSS or SCSS in Airtable Custom blocks.

Working of making this a github gist.


Richard_Sinn wrote:

Hi Ronen,

Thank you for the feedback, especially around your experiences with the browserify plugins/packages. More robust CSS support for Blocks is something we are definitely considering and hoping to improve in the future.

Thanks,
Richard


Hey @Richard_Sinn, did you consider using webpack instead of browserify? It has builtin support for importing css files from js files, as follows:

import css from 'file.css';

Cheers,
Ronen Babayoff
Superblocks.at


Ashwin_P wrote:

Here’s how I write CSS locally during development.

First of all, I write SCSS and not CSS directly.

  1. I write styles.scss. I compile it to “css” using SCSS compiler in watch mode
    sass --watch frontend/styles/main.scss frontend/styles/styles.css

Now main.scss gets converted to styles.css.

  1. Then I convert styles.css to a styles.js which is the whole css file converted to a string by surrounding with template literals.

So the styles.js looks like:

export default `
    .classname: {
        border: 1px solid red;
    }
    ... rest of your styles css here
`;
  1. This styles.js can be imported in your Custom block and passed to loadCSSFromString
import stylesString from './styles/styles.js';;
import { loadCSSFromString } from '@airtable/blocks/ui';
loadCSSFromString(stylesString);

And this allows me to update my stylesheets with hot reloading.

I wrote about this here - How to import CSS or SCSS in Airtable Custom blocks.

Working of making this a github gist.


@Ashwin_P,

Thanks for the blog write-up on this - it was helpful. I have a couple questions (for you or anyone else willing to answer), if you don’t mind helping a JavaScript novice…

  1. Is there no way just write CSS in its own file in frontend/styles/styles.css and then stringify/serialize the contents of that file in the index.js, such that you could just loadCSSFromString(mySerializedCSSFile)?

  2. In lieu of the option above, this file-watcher code that you wrote – I’m not sure I understand where that goes in order for it to be watching the CSS file and hot-reloading. Does it need to be required into index.js so that it is running when $ block run is invoked?

Thank you


  • Participating Frequently
  • 6 replies
  • September 11, 2020

@Jeremy_Oglesby, I save my styles as styles.js and use VS-Code to color/lint the file as CSS. This has been the easiest way for me to keep styles separate without extra environmental overhead.

index.js

import stylesString from './styles.js';
loadCSSFromString(stylesString);

styles.js

export default `

.className {
    color: blue;
    width: 100%;
}

`;

Brady_Menegay wrote:

@Jeremy_Oglesby, I save my styles as styles.js and use VS-Code to color/lint the file as CSS. This has been the easiest way for me to keep styles separate without extra environmental overhead.

index.js

import stylesString from './styles.js';
loadCSSFromString(stylesString);

styles.js

export default `

.className {
    color: blue;
    width: 100%;
}

`;

Thanks for the response, @Brady_Menegay. This definitely looks like a simpler route to take.

Do you still get CSS syntax perks while writing inside the string template like this? (such as auto-indent, intellisense suggestions, etc)

In your index.js, you are importing something called styleString, but in your styles.js you aren’t exporting something called styleString - you are just exporting the string template itself… is styleString just an arbitrary variable name into which that string template is being saved by default as the only thing exported by styles.js? Am I understanding that correctly?

Thank you, @Brady_Menegay


  • Participating Frequently
  • 6 replies
  • September 11, 2020
Jeremy_Oglesby wrote:

Thanks for the response, @Brady_Menegay. This definitely looks like a simpler route to take.

Do you still get CSS syntax perks while writing inside the string template like this? (such as auto-indent, intellisense suggestions, etc)

In your index.js, you are importing something called styleString, but in your styles.js you aren’t exporting something called styleString - you are just exporting the string template itself… is styleString just an arbitrary variable name into which that string template is being saved by default as the only thing exported by styles.js? Am I understanding that correctly?

Thank you, @Brady_Menegay


@Jeremy_Oglesby

You are exactly right. Since styles.js is exporting a single string, styleString that is the variable name I chose. I think of it like assigning any other variable. let styleString = import './style.js';

I can only speak to VS-Code, but yes. After setting the language for this specific file I get the below:


Brady_Menegay wrote:

@Jeremy_Oglesby

You are exactly right. Since styles.js is exporting a single string, styleString that is the variable name I chose. I think of it like assigning any other variable. let styleString = import './style.js';

I can only speak to VS-Code, but yes. After setting the language for this specific file I get the below:


Awesome - I use VS Code as well, so this will work just fine for me.


  • Participating Frequently
  • 6 replies
  • September 11, 2020
Jeremy_Oglesby wrote:

Awesome - I use VS Code as well, so this will work just fine for me.


A word of warning, I did notice the first style can be seen as an error, depending on the plugins I have active. Then I have problems I add a placeholder class to the top of my CSS file. I think the brackets fool VS-Code into ignoring the other syntactical “errors”


  • New Participant
  • 2 replies
  • December 22, 2022

If anyone is stumbling upon this in 2022, I think this has gotten way easier now.

From the blocks-cli Readme:


The new CLI supports css files within your extension by default. The default webpack bundler is configured with css-loader and style-loader. This means you can import a css file into your extension. Example:
// styles.css
.red {
  color: red;
}
import {initializeBlock} from '@airtable/blocks/ui';
import React from 'react';
import './styles.css'

function MyExtension() {
    return <div className="red">Hello world</div>;
}

initializeBlock(() => <MyExtension />);

You can even change the webpack config to support sass files:


wnm wrote:

If anyone is stumbling upon this in 2022, I think this has gotten way easier now.

From the blocks-cli Readme:


The new CLI supports css files within your extension by default. The default webpack bundler is configured with css-loader and style-loader. This means you can import a css file into your extension. Example:
// styles.css
.red {
  color: red;
}
import {initializeBlock} from '@airtable/blocks/ui';
import React from 'react';
import './styles.css'

function MyExtension() {
    return <div className="red">Hello world</div>;
}

initializeBlock(() => <MyExtension />);

You can even change the webpack config to support sass files:


This no longer works. I get Bundle Error: Unexpected token


Reply