11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.
https://www.11ty.dev/
MIT License
16.83k stars 487 forks source link

EleventyHtmlBasePlugin not updating URLs in CSS files #3004

Open tedw opened 1 year ago

tedw commented 1 year ago

Operating system

macOS 13.3.1

Eleventy

2.0.1

Describe the bug

I just tried using the HTML plugin for the first time and it worked great—except it didn’t update any URLs in my CSS file.

For example, I’m using @font-face to load some web fonts:

@font-face {
  font-display: fallback;
  font-family: "Manrope";
  font-style: normal;
  font-weight: 400;
  src: url("../fonts/manrope/manrope-400.woff2") format("woff2"),
       url("../fonts/manrope/manrope-400.woff") format("woff");
}

However the generated code lacks the pathPrefix resulting in 404s (both locally and after building):

@font-face {
  font-display: fallback;
  font-family: "Manrope";
  font-style: normal;
  font-weight: 400;
  src: url("/assets/fonts/manrope/manrope-400.woff2") format("woff2"),
       url("/assets/fonts/manrope/manrope-400.woff") format("woff");
}

Not sure what the best way is to address this. For the time being I’m manually updating the paths in the generated files but would love to find a more automated solution.

Reproduction steps

  1. Create boilerplate Eleventy site
  2. Add HTML base plugin
  3. Set pathPrefix to anything
  4. Add a CSS file and include a webfont using @font-face
  5. Build the site
  6. Check the font path in the generated CSS

Expected behavior

I’d love to find a way to auto update all URLs in CSS files. At the very least, I think it would be helpful to add a note about this in the HTML base docs.

Thanks!

Reproduction URL

No response

Screenshots

No response

ezramechaber commented 3 months ago

Having this same issue - curious if you solved this for your own purposes, @tedw

tedw commented 3 months ago

@ezramechaber I ended up removing the HTML plugin and doing it via Webpack, since my project already used it.

I stored the URL prefix in a custom data file so I could reference it in my templates and in the Webpack config file. It defaults to / locally but is changed to /example/ in production.

src/data/app.js

const app = {
  url: process.env.NODE_ENV == 'production' ? '/example/' : '/',// must end with trailing slash
};

module.exports = app;

Example usage in template:

<link rel="apple-touch-icon" sizes="180x180" href="{{ app.url }}apple-touch-icon.png">

I then imported my data file into the Webpack config so I can prefix publicPath with app.url in production.

webpack.config.js

// Import app.js so we can get the URL prefix
const app = require('./src/data/app.js');

const isDev = process.env.NODE_ENV == 'development';

module.exports = {
  // Note: This is a simplified example, you’ll need to add `plugins`, `module`, etc. for it to work (see https://github.com/clenemt/eleventy-webpack)
  mode: isDev ? 'development' : 'production',
  entry: {
    main: [
      path.resolve(__dirname, 'src/assets/scripts/main.js'),
      path.resolve(__dirname, 'src/assets/styles/main.scss')
    ]
  },
  output: {
    filename: isDev ? '[name].js' : '[name].[contenthash].js',
    path: path.resolve(__dirname, '_site/assets'),
    publicPath: isDev ? '/assets/' : `${app.url}assets/`,// <-- This is where I update the path
  },
  resolve: {
    alias: {
      // Helpful alias for importing assets
      assets: path.resolve(__dirname, 'src/assets')
    }
  }
};
ezramechaber commented 3 months ago

@tedw thanks for writing this up!

Because my css folder was a subfolder of assets, which was the parent folder i needed to access, I solved using ../fonts to get assets/fonts.

tedw commented 3 months ago

@ezramechaber No prob! I should note the original reason I was trying to change the path was because my client wanted their Eleventy microsite to live in a subdirectory of their existing main site. This is why I needed different URL paths locally than in production. Normally, using a relative path to the font files works fine for me, just like your solution.