Skip to content

eligrey/fragment-directives

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fragment Directives API explainer

Authors:

Participate

Introduction

Fragment directives are instructions for user agents to perform some action. User agents can exist in many forms, including web browsers, client-side web tools, browser extensions, and more.

Recently, browsers have started to adopt the URL Fragment Text Directives aka scroll-to-text specification. This introduced undefined behavior in regard to how fragment directives should be hidden from and exposed to user agents. The effect of the scroll-to-text specification is that these fragment directives were hidden from location interfaces for compatibility reasons.

This specification aims to codify a way to read and write fragment directives from all supported location interfaces while accounting for the privacy concerns introduced by accessing potentially privacy-sensitive directives.

Motivating Use Cases

One motivating use case to re-expose these fragment directives is for websites to be able to implement their own custom navigate-to-text logic. Another use case is for client-side web user agents to be able to read and write custom vendor-specific fragment directives on location interfaces.

Privacy

Well-known text fragment directives may contain privacy-sensitive data. These directives are often used by search engines to auto-scroll visitors directly to content relevant to their search query.

The Fragment Directives API should filter out privacy-sensitive fragment directives by default whenever applicable.

API

The Fragment Directives API exposes a new requestFragmentDirectives method on the Navigation interface and a new setFragmentDirectives method on the URL, Location, HTMLAnchorElement, and HTMLLinkElement interfaces.

The navigation.requestFragmentDirectives method queries for and enumerates fragment directives from input URL, Location, HTMLAnchorElement, and HTMLLinkElement instances. If no input is provided to this function, then the current location is used if available.

This method takes an optional options object with an optional includeSensitive field. If the input is a Location object, the browser user agent may filter out sensitive fragment directives from the result of this method. Additionally, the browser user agent may require a secure context and prompt the user to allow access to sensitive fragment directives from the website calling this method. As there is only one known privacy-sensitive fragment directive, browser user agents may choose to prompt with the user with a message equivalent to "[website origin] wants to access in-page search terms" in the user's configured language.

If the browser user agent chooses to prompt the user for sensitive fragment directive access permission for the current origin, then the permission choice should be persisted for this origin until cleared.

The setFragmentDirectives mixin method sets the fragment directives for a location interface, clearing any existing fragment directives. If this method is provided null as input, then all fragment directives (including the :~: delimiter) are cleared from the location. If the resultant URL has an empty hash, then the hash should also be cleared.

Example use cases

Custom scroll-to-text behavior

This snippet could be invoked by a website to handle custom scroll-to-text or navigate-to-text logic. This logic could automatically open a specific view in a webapp that would normally be obscured or inaccessible, breaking normal scroll-to-text.

if (navigation.requestFragmentDirectives) {
  const directives = await navigation.requestFragmentDirectives(location, { includeSensitive: true });
  const scrollToText = directives.getAll('text');
  if (scrollToText) {
    // implement custom scroll-to-text / navigate-to-text
  }
}

Custom fragment directives

This snippet could be invoked by a JavaScript library in order to read and write custom vendor-specific fragment directives. This allows vendors to provide configuration data over URLs without interfering with the host site's routing logic.

// on initial site:
const url = new URL('//another-site.example', location);
if (url.setFragmentDirectives) {
  url.setFragmentDirectives(new URLSearchParams('my-custom-directive=...'));
}
navigation.navigate(url);

// on another-site.example:
if (navigation.requestFragmentDirectives) {
  const directives = await navigation.requestFragmentDirectives();
  const customDirective = directives.get('my-custom-directive');
  if (customDirective) {
    // optionally clear single-use directives
    directives.delete('my-custom-directive');
    location.setFragmentDirectives(directives);

    // handle directive
    handleMyCustomDirective(customDirective);
  }
}

Polyfills

This can be polyfilled in the currently-shipping versions of Chrome (126), Edge (126), Firefox (127), and Safari (17.5).

Interface definitions

type LocationLike = Location | URL | HTMLAnchorElement | HTMLLinkElement;

interface RequestFragmentDirectives {
  (source?: LocationLike, options?: RequestFragmentDirectivesOptions): Promise<URLSearchParams>;
}

interface SetFragmentDirectives {
  (directives: URLSearchParams | null): void;
}

interface RequestFragmentDirectivesOptions {
  includeSensitive?: boolean;
}

interface NavigationRequestFragmentDirectives extends Navigation {
  requestFragmentDirectives: RequestFragmentDirectives;
}

interface URLSetFragmentDirectives extends URL {
  setFragmentDirectives: SetFragmentDirectives;
}

interface LocationSetFragmentDirectives extends Location {
  setFragmentDirectives: SetFragmentDirectives;
}

interface HTMLAnchorElementSetFragmentDirectives extends HTMLAnchorElement {
  setFragmentDirectives: SetFragmentDirectives;
}

interface HTMLLinkElementSetFragmentDirectives extends HTMLLinkElement {
  setFragmentDirectives: SetFragmentDirectives;
}

Stakeholder Feedback / Opposition

  • Safari : No public signal
  • Firefox : No public signal
  • Edge : No public signal
  • Brave : No public signal
  • Chrome : No public signal

About

Fragment Directives API

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published