Importer

Swift
public protocol Importer: Sendable

Methods required to implement a stylesheet importer.

Importers resolve @import, @use, and @forward rules in stylesheets. The methods are called back by the compiler during compilation. You don’t need this to include the contents of a filesystem directory: see instead ImportResolver.loadPath(_:).

You could use this to present network resources or dynamically constructed content.

An import has two steps: canonicalization and loading.

Importer.canonicalize(...) is always called first with whatever URL text the user has written in their rule. The routine interprets that and returns a canonical URL that is absolute with a scheme.

The compiler most likely implements a cache based on canonical URLs. If the compiler does not have a stylesheet cached for the canonical URL then it calls Importer.load(...) with that URL to get at the content.

File extension rules

Sass itself handles imports from the filesystem using various filename conventions. Users of your importer mostly likely expect the same behavior if the URLs you are importing resemble filenames with extensions and directories.

From the Sass embedded protocol documentation:

The importer should look for stylesheets by adding the prefix _ to the URL’s basename, and by adding the extensions .sass and .scss if the URL doesn’t already have one of those extensions. For example, given the URL “foo/bar/baz” the importer should look for:

  1. foo/bar/baz.sass
  2. foo/bar/baz.scss
  3. foo/bar/_baz.sass
  4. foo/bar/_baz.scss

Given the URL “foo/bar/baz.scss” the importer should look for:

  1. foo/bar/baz.scss
  2. foo/bar/_baz.scss

If the importer finds a stylesheet at more than one of these URLs then it must throw an error indicating that the import is ambiguous.

If none of the possible paths are valid then the importer should perform the same resolution on the URL followed by /index. In the example above, it should additionally look for:

  1. foo/bar/baz/_index.sass
  2. foo/bar/baz/index.sass
  3. foo/bar/baz/_index.scss
  4. foo/bar/baz/index.scss

If more than one of these implicit index resources exist then the importer must throw an error indicating that the import is ambiguous.


Topics

func canonicalize(ruleURL: String, context: ImporterContext) async -> URL?

Convert an imported URL to its canonical format.

The returned URL must be absolute and include a scheme. If the routine happens to be called with a resource’s canonical URL (including something the routine previously returned) then it must be returned unchanged.

Declaration
Swift
func canonicalize(ruleURL: String, context: ImporterContext) async throws
    -> URL?
Parameters
ruleURL

The text following @import or @use in a stylesheet.

context

Some details about the import.

Throws

Only when ruleURL cannot be canonicalized: it is definitely this importer’s responsibility to do so, but it can’t. For example, if the request is “foo” but both foo.sass and foo.css are available. If “foo” didn’t match anything then the importer should return nil instead.

Compilation will stop, quoting the description of the error thrown as the reason.

Return Value

The canonical absolute URL, or nil if the importer doesn’t recognize the import request to have the compiler try the next importer.

func load(canonicalURL: URL) async -> ImporterResults?

Load a stylesheet from a canonical URL

Declaration
Swift
func load(canonicalURL: URL) async throws -> ImporterResults?
Parameters
canonicalURL

A URL previously returned by canonicalize(...) during this compilation.

Throws

If the stylesheet cannot be loaded. Compilation will stop, quoting the description of this error as the reason.

Return Value

The stylesheet and its metadata, or nil if the canonicalURL doesn’t resolve to a stylesheet.

var noncanonicalURLSchemes: [String]

Note

Has a default implementation.

The noncanonical URL schemes for this importer.

If set, this promises that the results of canonicalize(...) will never use one of these schemes. Any absolute ruleURLs that use one of these schemes will have context.containingURL set.

By default there are no non-canonical URL schemes.

Default Implementation

An empty list.

Declaration
Swift
var noncanonicalURLSchemes: [String] { get }