angular: styleUrls does not work with root path "/"

styleUrls: ["dist/stylesheet/App.css"] // this works perfectly
styleUrls: ["/dist/stylesheet/App.css"] // this does not work

any idea?

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 25
  • Comments: 48 (11 by maintainers)

Commits related to this issue

Most upvoted comments

+1

Yes, this is a valid bug right now. Thanks for reporting!

On Sun, Nov 1, 2015 at 5:58 PM NoNameSheep notifications@github.com wrote:

https://github.com/angular/angular/blob/master/modules/angular2/src/core/compiler/style_url_resolver.ts#L18

I’m not sure why. It seems Angular2 is agnostic about file path like ./, /. Is this intended?

— Reply to this email directly or view it on GitHub https://github.com/angular/angular/issues/4974#issuecomment-152888603.

+1

It’s 2017 this still isn’t fixed!

+1, using final release.

So I just ran into this while learning Angular. Considering the surprise-factor and longevity of the bug this should be highlighted in the docs until fixed.

won’t implement since absolute absolute paths have different meaning for AoT vs JIT.

I can’t believe this bug is still here!!! I can’t import my CSS! This is has been an issue for over a year!

@Still open?? 😢

Still a problem in 2.0.0-beta.12

@rocco-scaramuzzi, that fix doesn’t always works, because if you use a router, or the same script in multiple pages with different paths, then the …/ piece sometimes will not be sufficient. I actually ended up writing

getRootRelativePath: function(currentPath = window.location.pathname) {
    let path = currentPath
      .split('/')
      .slice(2)
      .map(() => '..')
      .join('/');

    return path.replace(/^\//, '');
  }

But I shouldn’t have to write this in order to use css. I can send a PR with a fix for this, I just need more insight about why did they make this restriction, if it was a mistake or if it’s with some logic behind.

BTW, I discovered you can also use the moduleId property in the component, to give a relative path. https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html -> look for moduleId

@Component({
  moduleId: module.id,
  styleUrls: ['relativeUrl.css']
})

My workaround is to start my absolute path with the two dots parent directory.

styleUrls: [“/poster-manager-app/asset-management/asset-management.component.css”] // does not work styleUrls: [“…/poster-manager-app/asset-management/asset-management.component.css”] // DOES work by adding “…/”

NOTE: this is my temporary workaround which in some cases won’t work, for more details please read @diestrin comment below.

I hope it helps

For those who still need a fix to this for JIT (which has fewer and fewer use cases as of 2018… but I have one of them here), the following monkey patch works:

const fs = require('fs');

const fn = 'node_modules/@angular/compiler/compiler.js';

const source = fs.readFileSync(fn, 'utf-8');
const patched = source.replace(
  `if (url == null || url.length === 0 || url[0] == '/')`,
  `if (!url) /* match previous length for source maps */`
);
fs.writeFileSync(fn, patched);

+1 final release

@chrisbouchard

Your post led me to look into compiler.umd.js, myself and I discovered that if I make this change, root url paths seem to work for styles:

Original:

function isStyleUrlResolvable(url) {
      if (isBlank(url) || url.length === 0 || url[0] == '/') // this is the boolean right here that breaks it
          return false;
      var schemeMatch = url.match(_urlWithSchemaRe);
      return schemeMatch === null || schemeMatch[1] == 'package' || schemeMatch[1] == 'asset';
  }

Changed:

function isStyleUrlResolvable(url) {
      if (isBlank(url) || url.length === 0) // if we remove the last condition, root path styleUrls work
          return false;
      var schemeMatch = url.match(_urlWithSchemaRe);
      return schemeMatch === null || schemeMatch[1] == 'package' || schemeMatch[1] == 'asset';
  }

It’s clear there is some explicit reason this logic was put in place, but I’m having a hard time understanding why.

Same here, I still have the problem.

Still not working, 2.0.0-rc.1

There’s a comment in extractStyleUrls:

if (!isStyleUrlResolvable(url)) {
  // Do not attempt to resolve non-package absolute URLs with URI scheme
  return m[0];
}

Which makes me wonder if isStyleUrlResolvable needs to differentiate between URLs from styleUrls and from @imports.

Still seems to be an issue in 2.0.0-beta.11

It is a bit unfortunate because absolute paths work with templateUrls.

I’ve found this bug is only a problem when I navigate away from index.html and refresh the page. There’s not a good way to load the style because it imports relative to the current url. So if I navigate from / -> /user/5, then refresh, the styleUrl requested turns into /user/app/components/user/user.css instead of /app/components/user/user.css