presta icon indicating copy to clipboard operation
presta copied to clipboard

Attach arbitrary props to build context

Open estrattonbailey opened this issue 3 years ago • 2 comments

Could add, say, a CSS-in-JS instance before build, and extract it to a file after all pages have built.

This would be configured in presta.config.js. That file is currently supported to supply CLI options as a config, but we could just add anything from the config to context, or use a specific object, like:

// presta.config.js

// instead of specifying in the CLI
export const files = './pages/**/*.jsx'

const someGlobalContext = {}

// called on every render
export async function createContext() {
  return {
    someGlobalContext,
    css: createCssInstance(), // attach some CSS-in-JS solution, or similar
  }
}

People could also use this to fetch global data for every page. Could be a sort of foot-gun in that sense though bc it would slow down rendering 🤔

estrattonbailey avatar May 31 '21 13:05 estrattonbailey

Today I was playing around and used the libraries extract function to create a stylesheet with a random name and then add it within the links in html, I named it css simply because prettier understands the css name (same happens with all languages) and styles the templated string as the language.

Here's my example:


// Create the single string
function interpolate(strings: TemplateStringsArray, interpolations?: string[]) {
  return strings.reduce((final, str, i) => {
    return `${final}${str}${!!interpolations[i] ? interpolations[i] : ""}`;
  }, "");
}

/**
 * Named css for prettier formatter
 */
function css(strings: TemplateStringsArray, ...interpolations: string[]) {
  const styleString = interpolate(strings, interpolations);
  const number = Math.random() * Number.MAX_SAFE_INTEGER;
  // Get pseudorandom sheetName
  const sheetName = `sheet-${number.toString(36)}`;
  return extract(styleString, "css", sheetName);
}

const red = "#ff0000";
const styles = css`
  h1 {
    font-size: 50px;
    color: ${red};
  }
`;

export async function handler(props) {
  return html({
    head: {
      link: [{ rel: "stylesheet", href: styles }],
    },
    body: `<h1>Hello world!</h1>`,
  });
}

cjenaro avatar Jun 11 '21 02:06 cjenaro

@cjenaro very nice! Great use case. I updated the description above with more details.

estrattonbailey avatar Jun 11 '21 15:06 estrattonbailey