URL query parameter API
JBrowse Web supports URL parameters for initializing a session.
For embedded components like @jbrowse/react-linear-genome-view2, the consuming application implements URL parameter handling itself.
Query string or hash fragment
Every parameter on this page works in either place: ?config=…&loc=… or
#config=…&loc=…. A fragment is never sent to the server, so a long value — an
encoded-/json- session, a whole session spec, a big
&sessionTracks= — cannot trip the request-line limit that answers a long query
string with HTTP 414. That is why the Share button writes its two inline formats
as hash URLs.
If the fragment contains an =, JBrowse reads its parameters only from there
and ignores the query string, so moving one long parameter into the fragment
means moving them all: ?config=my.json#session=spec-{…} loads the default
config.json, not my.json.
Linear genome view (simple)
A simplified URL format for launching a single linear genome view:
http://host/jbrowse2/?config=test_data/config.json&loc=chr1:6000-7000&assembly=hg19&tracks=gene_track,vcf_track
&assembly=, &loc=, ®ions=, &nav=, &tracks=, &tracklist=,
&highlight=, &sessionTracks= and &extendSession= apply only to this single
linear genome view launch — every other launch type carries the same settings
inside the session it loads. ?config=, &sessionName=, &hubURL=,
&renderer= and &session= work for any launch type.
Two more are documented with the feature they belong to: &password= with
&session=share-, and &adminKey= in
JBrowse CLI admin server.
?config=
?config=test_data/volvox/config.json
A path to a JBrowse 2 config file, relative to the current folder on disk,
fetched by the client. If ?config= is omitted, JBrowse looks for config.json
in the current folder (e.g. http://host/jbrowse2/config.json), which is what
the @jbrowse/cli tool sets up by default.
The special value ?config=none skips loading a config file entirely. This is
useful with &hubURL= (below), which supplies its own assemblies and tracks.
To change the default without putting ?config= in every link, set
window.__jbrowseConfigPath in the <head> of JBrowse's index.html — see
Avoiding stale config, which uses the same mechanism. An
explicit ?config= still wins over it.
&assembly=
&assembly=hg19
&assembly= refers to the name field of an entry in the assemblies array of
config.json.
&loc=
&loc=chr1:6000-7000
Navigates to this region on load. Accepts the formats shown below.
Example strings
&loc=chr1:6000-7000 // using - notation for range
&loc=chr1:6000..7000 // using .. notation for range
&loc=chr1:7000 // centered on this position
&loc=chr1 // the whole of one chromosome
&loc=chr1%206000%207000 // refName, start and end, whitespace separated
&loc=chr1:34M-35M // coordinates abbreviated with a unit suffix
&loc=GENEID // if you have used `jbrowse text-index`
A coordinate may be written with a k, M or G suffix, optionally followed
by b or bp, so chr1:34M-35M, chr1:1.5Mb-2Mb and chr1:500kb-600kb are
all accepted. These are expanded to whole base pairs on load, and the location
box then reads back the full number.
Navigating via &loc=GENEID requires a text index built with
jbrowse text-index.
Several whitespace-separated locstrings open a discontinuous view showing each
region in turn — a gene and the partner it is fused to, an allele beside the
sequences it derives from. The space is URL-encoded as %20:
&loc=chr3:25,325,000-25,361,000%20chr10:58,716,500-58,718,500
This is the same form the location box displays once a view holds more than one
region, so what you copy out of it pastes back into a URL. To open a
whole-genome view restricted to particular chromosomes instead, use
®ions=.
By default &loc= (and &assembly=) start a fresh session, ignoring the
config's defaultSession;
&extendSession=true navigates that
session instead of replacing it.
®ions=
&assembly=hg38®ions=chr1,chr2,chr3
Restricts the whole-genome overview to this comma-separated subset of the
assembly's chromosomes, in the order given, handy for dropping unplaced/alt
contigs or reordering. Names resolve through the assembly's aliases. It is
ignored when &loc= is set, and it requires &assembly=. This is the
simple-URL form of the session-spec
displayedRegionNames field, and takes the same
globs.
&highlight=
&highlight=chr1:6000-7000
Creates a highlight over the specified region when combined with &assembly= and &loc=.
Multiple highlight locations can be specified by delimiting locations with a
space (URL-encoded as %20):
&highlight=chr1:6000-7000%20chr1:7100-7200
Always pass &assembly= alongside &highlight=. Highlights are stored by
assembly name so downstream features (e.g. bookmarking from the chip menu) can
resolve them. Without one, a highlight still renders when its refName matches a
displayed region, but it is not portable across assemblies and may break actions
that need a fully-qualified region. The same applies to view.highlight in a
session JSON: include assemblyName on each entry.
view.highlight entries also accept optional color and label fields, both
when authoring a session JSON directly and via the URL by passing a JSON object
(URL-encoded) instead of a loc string:
{
"refName": "11",
"start": 32200274,
"end": 32203877,
"assemblyName": "mm39",
"color": "rgba(240, 128, 128, 0.3)",
"label": "R2_intron"
}
coloroverrides the theme highlight color, used as-is, so explicit alpha is preservedlabelis shown inline next to the chip icon and in the chip tooltip
URL form (URL-encode the JSON):
&highlight={"refName":"11","start":32200274,"end":32203877,"color":"rgba(240,128,128,0.3)","label":"R2_intron"}
JSON highlights use the same %20 space delimiter, and loc strings and JSON
objects can be mixed in one &highlight= value.
This highlights a region, over every track at once, and needs coordinates. To
box a single feature by name, and sort it to the top of its track's layout,
see
featureHighlights.
&tracklist=
&tracklist=true
Opens the track selector on load. Default: false.
&nav=
&nav=false
Turns off the navigation bar of the linear genome view. Default true.
&tracks=
&tracks=gene_track,vcf_track
A comma-separated list of trackIds, which the config.json defines. A trackId
added by &sessionTracks= can be named here too.
&sessionTracks=
&sessionTracks= dynamically adds a track to the session. It can also add a
FromConfigAdapter track, specifying features inline as JSON — BLAST hits from
the URL bar, say.
A track over a data file needs no type or adapter — the extension gives
both:
&sessionTracks=[{"trackId":"reads","uri":"https://example.com/sample.bam","assemblyNames":["hg38"]}]
Nothing implies the assembly for a session track, so name it — see the shortest track. The full form below is what a track with no data file needs.
https://jbrowse.org/code/jb2/main/?config=test_data/volvox/config.json&loc=ctgA:1-800&assembly=volvox&tracks=gff3tabix_genes,volvox_filtered_vcf,volvox_microarray,volvox_cram,url_track&sessionTracks=[{"type":"FeatureTrack","trackId":"url_track","name":"URL track","assemblyNames":["volvox"],"adapter":{"type":"FromConfigAdapter","features":[{"uniqueId":"one","refName":"ctgA","start":100,"end":200,"name":"Boris"}]}}]
This creates a track with a single feature at ctgA:100-200.
The value is an array of track configs. Pretty-printed, the one above is:
[
{
"type": "FeatureTrack",
"trackId": "url_track",
"name": "URL track",
"assemblyNames": ["volvox"],
"adapter": {
"type": "FromConfigAdapter",
"features": [
{
"uniqueId": "one",
"refName": "ctgA",
"start": 100,
"end": 200,
"name": "Boris"
}
]
}
}
]
&sessionName=
&sessionName=My%20Custom%20Session
Sets the session name displayed in the header bar. It works with all session types:
- Default sessions (loaded from config)
- Session specs (
&session=spec-...) - Hub sessions (
&hubURL=...)
Use it to give URL-launched sessions a meaningful name; without it the name is auto-generated with a timestamp. URL-encode the value if it contains spaces or special characters.
&hubURL=
&hubURL=https://example.com/hub.txt&config=none
Loads one or more UCSC track hubs as a session (multiple hubs as a
comma-separated list), typically combined with ?config=none since the hub
supplies its own assemblies and tracks.
Add &loc= and &assembly= to open the hub at a particular place. &assembly=
is required for this: it names the hub genome that &loc= resolves against.
?config=none&hubURL=https://example.com/hub.txt&assembly=GCF_019202715.1&loc=chr1:1-100000
&sessionTracks= works alongside a hub, registering its track configs into the
hub session, so &tracks= can name one of them beside the hub's own tracks.
&hubURL= opens each hub with a single linear genome view. For anything beyond
that — several views over a hub, a workspace layout, or a dotplot — put the hub
in a session spec's sessionConnections instead.
See Opening track hubs by URL for the full workflow, including combining a hub with a config and loading several at once.
&renderer=
&renderer=webgl
Pins the backend tracks are drawn with, overriding automatic detection. Each value pins one backend:
webgpurequires WebGPUwebglskips WebGPU and uses WebGL2canvas2dskips both and draws in software.canvasis accepted as an alias for it
A pin never falls through to the next backend: if the one you named cannot start, tracks show an error saying so. Any other value is ignored, with a console warning naming the ones that work.
It is a debugging aid: trying each in turn says whether a blank or wrong-looking
track comes from the GPU path, see
my tracks are blank or render incorrectly.
JBrowse Desktop takes the same choice as a --renderer command-line flag, see
JBrowse desktop quick start.
&safeMode
&safeMode
Loads without the plugins this browser keeps for this configuration, see keeping a plugin for every visit. The list is left alone — the plugins are skipped for this load only, and the next one without the parameter runs them again.
Its own use is a plugin that crashes the app before any menu is on screen. The fatal error dialog offers the same thing as a button, and JBrowse turns them off by itself after a load that never finished; the parameter is for the case where neither has happened and you want to rule them out.
Bare, with no value, is how it is normally written. &safeMode=1 works too:
what counts is that the parameter is present.
Navigating within the default session
&extendSession=true alongside &loc= navigates a curated defaultSession
while keeping its tracks and settings, rather than replacing it:
?loc=chr1:100000-200000&extendSession=true
&loc=, &tracks=, &highlight=, &nav= and &tracklist= are then applied
to the first linear genome view of that defaultSession. The assembly comes
from that view, so &assembly= isn't needed. &sessionTracks= is not layered
on; a full session spec is the way to add a track config to a
curated session.
Which parameter decides the launch
A link can carry several of these at once, and they don't combine — one of them decides what opens and the rest are either layered onto it or dropped. The ranking, highest first:
&session=, in any of its forms (spec-,share-,encoded-,json-,local-). An explicit session always beats a stray&loc=. A value matching none of those prefixes is an error.&extendSession=truealongside&loc=/&assembly=, which navigates the config'sdefaultSession— see below. It outranks a hub, which would otherwise replace that session outright.&hubURL=. A hub brings its own assemblies and tracks, so a link carrying both a hub and&loc=navigates inside the hub: the shorthand rides along on top of the hub session.&loc=/&assembly=on their own, which build a fresh single linear genome view.- Nothing of the above, which opens the config's
defaultSession.
?config=, &sessionName= and &renderer= sit outside the ranking and apply
to whichever launch wins. &sessionTracks= applies to the hub launch and to the
shorthand on its own. It is not layered onto a default session or onto a
&session= of any kind, both of which have their own way to carry a track (a
spec's sessionTracks, the snapshot's own).
Session spec
A "session spec" encodes a session as JSON in the URL, as the value of
&session=, prefixed spec-:
&session=spec-{"views":[{"type":"LinearGenomeView","assembly":"volvox","loc":"ctgA:1-5100"}]}
Each view object lists the keys that view launches with, flat as below. A spec
is arguments to a view's launcher, so nothing is nested. A defaultSession in a
config writes the same settings under an init block instead, because there the
view is a saved state snapshot (see
Config / session files); moving a view
between the two means reshaping it, and pasting an init block into a spec is
reported. The embedded @jbrowse/react-linear-genome-view2 component takes the
init form via defaultSession.view.init.
Under the hood, each view's type dispatches to a LaunchView-<type>
extension point that builds the view
from the remaining fields. This is also how plugins add launchable view types
(see Plugin-provided view types).
{
"views": [
{
"assembly": "volvox",
"loc": "ctgA:1-5100",
"type": "LinearGenomeView",
"tracks": [
"gff3tabix_genes",
"volvox_filtered_vcf",
"volvox_microarray",
"volvox_cram"
]
}
]
}
The views array accepts multiple views opened simultaneously. Each can specify
loc, tracks, assembly, and view type. loc is optional, omitting it shows
the whole genome. Different view types accept different params: dotplot, for
example, takes two assemblies.
Session-wide fields
Alongside views, four top-level arrays furnish the session the views open
into. They are applied in this order — assemblies, then connections, then
tracks, then the views — so each can name what the ones before it registered.
A sessionTracks array registers track configs into the session before the
views open, equivalent to combining &sessionTracks= with a simple URL:
{
"sessionTracks": [
{
"type": "FeatureTrack",
"trackId": "my_track",
"name": "My track",
"assemblyNames": ["hg38"],
"adapter": { "type": "FromConfigAdapter", "features": [] }
}
],
"views": [
{
"type": "LinearGenomeView",
"assembly": "hg38",
"tracks": ["my_track"]
}
]
}
A sessionAssemblies array registers assemblies, the counterpart to
sessionTracks. Because assemblies are added first, sessionTracks and each
view's assembly can reference them by name. This makes a spec fully
self-contained: a novel assembly, its tracks, and the views over them (pair it
with ?config=none):
{
"sessionAssemblies": [
{
"name": "my_assembly",
"uri": "https://example.com/my_assembly.2bit"
}
],
"sessionTracks": [
{
"type": "FeatureTrack",
"trackId": "my_track",
"name": "My track",
"assemblyNames": ["my_assembly"],
"adapter": { "type": "FromConfigAdapter", "features": [] }
}
],
"views": [
{
"type": "LinearGenomeView",
"assembly": "my_assembly",
"tracks": ["my_track"]
}
]
}
A sessionConnections array attaches connections — UCSC track hubs, JBrowse
hubs. Each entry is a connection config, and it stays with the session: opening
the link never writes the connection into the config.json the instance serves.
The spec waits for each connection to finish fetching before launching its
views, so a view can name an assembly or a trackId the connection supplies:
{
"sessionConnections": [
{
"type": "UCSCTrackHubConnection",
"connectionId": "my_hub",
"name": "My hub",
"hubTxtLocation": { "uri": "https://example.com/hub.txt" }
}
],
"views": [
{
"type": "LinearGenomeView",
"assembly": "GCF_019202715.1",
"loc": "chr1:1-100000"
}
]
}
This is what &hubURL= does in its simple form, written out. Use the
spec form when the hub needs more than one view, a
layout, or a view type other than the linear genome
view.
A spec that lists no views leaves the connection to open its own view wherever
it starts (a single-file hub's defaultPos), which is what &hubURL= on its
own does. As soon as the spec has views of its own, those are the launch
instruction and the connection opens no view of its own.
A layout object tiles the views into a workspace rather than stacking them —
see tiled views.
&sessionName= sets a spec's session name, the same as for any
other launch type:
&session=spec-{...}&sessionName=My%20Analysis
Fields every view takes
id pins the created view's id so another view in the same spec can point at it
(e.g. an MsaView's connectedViewId). It is the one key the launcher reserves —
the rest of what every view takes comes from BaseViewModel and appears in each
view's table below, displayName among them.
displayedRegionNames is the spec form of ®ions=, with the
same meaning: when loc is omitted it restricts the whole-genome overview to
these chromosomes, in this order. Names may be globs. It
works on the linear genome view, the circular view, and each
axis of a dotplot — volvox showing only its two contigs, order
reversed:
{
"views": [
{
"type": "LinearGenomeView",
"assembly": "volvox",
"displayedRegionNames": ["ctgB", "ctgA"],
"tracks": ["gff3tabix_genes"]
}
]
}
Glob region names
An entry in displayedRegionNames containing * is a glob matched against the
refName, which makes a fragmented assembly tractable: ["*_hap1"] covers
sixteen scaffolds in one entry and survives the assembly being rebuilt. * is
the only metacharacter, so a refName with regex punctuation in it (chr1.1,
scaffold[2]) still matches literally.
A glob contributes its matches in the assembly's order, since that is the
only order it can mean; exact names contribute in the order you wrote them, so
an explicit list still controls layout. Entries already taken are skipped, which
makes ["chr1_hap1", "*_hap1"] read as "chr1 first, then the rest of hap1". A
name matching nothing is dropped, and a list that matches nothing at all is
reported.
Globs match the assembly's aliases as well as its own names, and match
case-insensitively, both the same as an exact entry does — so ["chr*"]
works on an assembly whose FASTA calls its chromosomes 1, 2, 3, and
["CHR*"] works wherever ["chr*"] does. A region is taken once however many
of its names match.
A glob does not separate the main chromosomes from the rest of a UCSC-style
assembly: that naming makes the unplaced and alt contigs extensions of the names
you want, so on hg38 chr* also takes chrUn_GL000195v1 and
chr1_KI270706v1_random, and even chr1* takes chr10 through chr19. There
is no negation. Globs are for name families an assembly separates — *_hap1,
*_MATERNAL, *_alt — and a main-chromosome subset is best written as a list.
The same field, and the same matching, is available on ®ions=,
on the circular view, on each axis of a
dotplot, and on each row of a
linear synteny view.
The dotplot and linear synteny import forms put this syntax in a text box — one beside each assembly, holding the comma-separated list this field takes — so a haplotype-per-axis plot can be reached by clicking. Empty means the whole assembly.
Advanced track configuration
The tracks array can contain either simple trackId strings or objects with
additional configuration options:
{
"views": [
{
"assembly": "volvox",
"loc": "ctgA:1-5100",
"type": "LinearGenomeView",
"tracks": [
"simple_track_id",
{
"trackId": "my_bam_track",
"displaySnapshot": {
"type": "LinearAlignmentsDisplay",
"height": 300
}
},
{
"trackId": "my_wiggle_track",
"displaySnapshot": { "minScore": 0, "maxScore": 100 }
}
]
}
]
}
Each track object supports the following properties:
trackId(required): The track identifier from config.jsondisplaySnapshot(optional): Initial display state. Can include:type: Override the display type (e.g.,LinearBasicDisplay,LinearArcDisplay,LinearAlignmentsDisplay)height: Display height in pixelscolor: Feature color for feature/wiggle tracks (a CSS color, or ajexl:expression for per-feature coloring)minScore,maxScore: Score range for quantitative tracksforceLoad: render even when the region trips the "too much data" gate, the declarative equivalent of the "Force load" button (see BaseLinearDisplay)- Other display-specific settings
trackSnapshot(optional): Initial track state such aspinned: true
The displaySnapshot fields can also be written directly on the track object as
a shorthand:
{ "trackId": "my_bam_track", "type": "LinearAlignmentsDisplay", "height": 300 }
is equivalent to the displaySnapshot form above. Any key other than trackId
and trackSnapshot is treated as a display setting. Use the explicit
displaySnapshot form when you also pass trackSnapshot, so the two stay
visually separated.
Linear genome view
A LinearGenomeView object takes two kinds of key, and the launcher sorts them
that way: the launch keys are the simple params
plus grow, which expands loc by that fraction on each side for context (so
0.2 pads 20%, and it is ignored without a loc); everything else is a
property the state model declares.
Linear genome view properties
Launch keys, resolved once on attach and then discarded, because they have
no direct representation in the view's state — assembly,
displayedRegionNames, grow, highlight, loc, nav, tracklist. There
are no others; a key outside this set and the table below is a typo, and the
launcher names it in a console warning rather than dropping it silently.
Properties, which are whatever the state model declares and the view restores natively:
| Property | What it does |
|---|---|
colorByCDS | color CDS segments by reading frame |
displayedRegions | currently displayed regions, can be a single chromosome, arbitrary subsections, or the entire set of chromosomes in the genome, but it not advised to use the entire set of chromosomes if your assembly is very fragmented |
displayName | displayName is displayed in the header of the view, or assembly names being used if none is specified |
hideHeader | drop the header bar entirely — location box, navigation buttons and overview |
hideHeaderOverview | keep the header, drop the whole-chromosome overview strip below it |
hideNoTracksActive | suppress the "No tracks active" placeholder, for an embed that opens with no tracks on purpose |
labelsVisible | controls whether highlight/bookmark chip labels are shown inline |
legacyBpPerPx | MIGRATION ONLY, and safe to delete once pre-window sessions are no longer in circulation. A snapshot written before the window was stored carries offsetPx and bpPerPx but not the width they were measured at, so the window they framed cannot be recovered. windowStartBp can (it is offsetPx * bpPerPx, no width needed); the width in bp cannot. This carries the old bpPerPx to the first measure, which adopts it at whatever width arrives — exactly what the old code did — and clears this. So an old link keeps its old behavior rather than being reinterpreted, and everything authored since restores its window. |
minimized | collapse the view to its header bar, keeping it in the session rather than closing it |
scalebarOnly | when true, only the header and coordinate scalebar are rendered |
showAminoAcids | draw translated codons on coding features once zoomed in far enough: an alternating per-codon shading, and the amino acid letters on top of it at base-level zoom. Independent of colorByCDS, which only recolors the segments by frame. |
showCenterLine | show the "center line" |
showCytobands | whether to show the "cytobands" in the overview scale bar (the resolved, capability-gated value is the effectiveShowCytobands getter) |
showGridlines | show the "gridlines" in the track area |
showHighlightChips | pins the interactive highlight chip (link icon + context menu) to every highlight band; off by default, where a band instead reveals its chip while the pointer is in it. This is what a screenshot needs, since nothing hovers in one |
showTrackOutlines | show the track outlines |
trackLabels | how to display the track labels, can be "overlapping", "offset", or "hidden", or empty string "" (which results in the LinearGenomeViewPlugin config default being used). the resolved value is the effectiveTrackLabels getter. see LinearGenomeViewPlugin https://jbrowse.org/jb2/docs/config/lineargenomeviewplugin/ docs for how conf is used |
trackSelectorType | vestigial: the hierarchical selector is the only one that exists, so this value is ignored. Retained because saved sessions and configs persist it. |
windowStartBp | Left edge of the viewport, in linearized bp — the concatenated displayedRegions space that offsetPx indexes, which carries no inter-region padding, so the two differ only by bpPerPx. May be negative, which is the view scrolled past the left end.The viewport is stored as the genomic WINDOW it frames rather than as the pixels that framed it, because pixels mean nothing without the width they were measured at and a snapshot does not carry one. Storing them anyway is why a session authored in a 1000px window used to open at 500px showing half the region its author was looking at, while the same location as a &loc= opened correctly — the two ways to share a view disagreed, and only the one that stores intent was right. |
windowWidthBp | Width of the viewport in bp. Zero means "not established yet": no width has been measured, so there is nothing to divide by. The first measure fills it in, and bpPerPx is windowWidthBp / width from then on. |
Three of those warrant more than their one-line description:
bpPerPxandoffsetPxare the zoom and the horizontal scroll.locreads, and it survives an assembly whose regions were rebuilt; reach for these two only to reproduce a viewport to the pixel.displayedRegionsgives the regions the view lays out as full{refName, start, end, assemblyName}objects.displayedRegionNamesnames the same thing by refName and is the shorter form; this is the form for showing part of a chromosome, which a name cannot express.showCytobandsandshowTrackOutlinesdefault to the visitor's own stored preference — both are menu settings persisted inlocalStorage, so a spec that omits them opens however that visitor last left them. Set them explicitly in a link that has to look the same for everyone.
Live example: alignments display settings
displaySnapshot can set any of the display's own settings — anything the
display's own menu offers. An alignments track colored by pair orientation, with
soft-clipped bases shown and an enlarged height:
{
"views": [
{
"assembly": "volvox",
"loc": "ctgA:1-10000",
"type": "LinearGenomeView",
"tracks": [
{
"trackId": "volvox_sv_cram",
"displaySnapshot": {
"height": 250,
"showSoftClipping": true,
"colorBy": { "type": "pairOrientation" }
}
}
]
}
]
}
Swapping showSoftClipping for showBezierConnections draws a curved connector
between the mates of each aberrant pair and across split-read junctions, so
structural-variant signal stands out over the pileup. Each curve is the same
horizontal-tangent shape a breakpoint split view draws:
{
"views": [
{
"assembly": "volvox",
"loc": "ctgA:1-10000",
"type": "LinearGenomeView",
"tracks": [
{
"trackId": "volvox_sv_cram",
"displaySnapshot": {
"height": 300,
"showBezierConnections": true,
"colorBy": { "type": "pairOrientation" }
}
}
]
}
]
}
Live example: feature track color
For a feature track (genes, BED, GFF), color in the displaySnapshot takes a
plain CSS color, or a jexl: expression to color per-feature. The genes track
in green:
{
"views": [
{
"assembly": "volvox",
"loc": "ctgA:1-50000",
"type": "LinearGenomeView",
"tracks": [
{
"trackId": "gff3tabix_genes",
"displaySnapshot": {
"color": "green"
}
}
]
}
]
}
To color by a feature attribute, use a jexl expression, e.g.
"color": "jexl:get(feature,'type')=='gene'?'blue':'gray'".
Live example: highlight a feature, and sort it to the top
&highlight= paints a band over a region, drawn by the view
across every track at once. To box one feature — a gene, transcript or
variant, at whatever row and height its own track laid it out — set
featureHighlights on the display. It is the same state the right-click
"Highlight feature" item and a feature search write, and every canvas display
carries it
(LinearBasicDisplay,
LinearVariantDisplay, and the rest):
{
"views": [
{
"assembly": "volvox",
"loc": "ctgA:1-50000",
"type": "LinearGenomeView",
"tracks": [
{
"trackId": "gff3tabix_genes",
"displaySnapshot": {
"height": 200,
"featureHighlights": [{ "refName": "ctgA", "name": "EDEN" }]
}
}
]
}
]
}
A highlight also sorts its feature to a top row of that track, ahead of the row packer's usual order, and holds it there across pan and zoom. On a dense annotation track the named gene is then boxed and first in the lane. Only a declarative highlight sorts: the right-click one marks a feature the user just clicked and leaves it where the packer put it.
Each entry names one feature, either way:
- By name —
{"refName": "ctgA", "name": "EDEN"}. The feature's label, matched exactly and case-insensitively within that refName. Prefer this. - By span —
{"refName": "ctgA", "start": 1049, "end": 9000}, in interbase (0-based half-open) coordinates, matched within ±1bp of the track's own record.
A location box reads ctgA:1,050-9,000 for that same feature — 1-based and
inclusive — so coordinates copied off the screen are a base short at the start
and match nothing. An entry may carry both forms, in which case name is the
fallback used when the span misses. A name that is genuinely ambiguous (a gene
and its same-named transcript) boxes both.
A span that resolves to nothing logs a console warning naming the coordinates, once data covering it has loaded. A name that resolves to nothing stays silent — it is indistinguishable from a feature elsewhere on the contig that has not been fetched yet. To clear, use the clear-highlights button that appears in the view header while anything is highlighted, or the track menu's "Clear N highlights".
Circular view
The circular view shows the whole genome, so there is no loc. It takes
assembly, tracks, displayedRegionNames (which chromosomes get an arc, in
that order — globs allowed, so a circle can drop the
unplaced contigs that would each claim a wedge), and height. The circle
auto-fits its container, so height is what sizes the drawing.
{
"views": [
{
"assembly": "volvox",
"type": "CircularView",
"tracks": ["volvox_sv_test"]
}
]
}
Circular view properties
As with the linear genome view, the spec also takes the view's own declared properties:
Launch keys, which name something to do on load rather than state the view holds:
| Launch key | What it does |
|---|---|
assembly | the assembly whose chromosomes the circle draws. Optional because a spec view is untyped user input; without one the view opens on its import form |
displayedRegionNames | whole chromosomes to draw, in this order; the rest of the assembly's contigs are left off the circle |
Properties, which are whatever the state model declares and the view restores natively:
| Property | What it does |
|---|---|
autoFit | whether the view keeps re-fitting to its container on resize. Cleared once the user manually zooms/pans so their view (persisted via bpPerPx/offsetRadians) is preserved across resizes and reloads. |
bpPerPx | the zoom level, base-pairs per pixel. Capped by minimumRadiusPx, and refit over by the first resize unless autoFit is false. |
disableImportForm | suppress the import form even on an error — what the SV inspector's circle wants, since its assembly comes from the sheet beside it and a form there would offer a control that cannot work |
displayName | displayName is displayed in the header of the view, or assembly names being used if none is specified |
height | the height of the view in pixels. The circle auto-fits its container, so this is what sizes the drawing. |
hideTrackSelectorButton | chrome switch, for an embed that drives the view itself |
hideVerticalResizeHandle | chrome switch, for an embed that drives the view itself |
minimized | collapse the view to its header bar, keeping it in the session rather than closing it |
minimumRadiusPx | how far in the circle may be zoomed, as a floor on the radius; it is what caps bpPerPx |
minVisibleWidth | arcs thinner than this many pixels are elided instead of drawn, which is what stops a few thousand unplaced contigs becoming a ring of hairlines |
offsetRadians | similar to offsetPx in linear genome view |
paddingPx | blank margin between the circle and the edge of the figure |
spacingPx | the gap drawn between adjacent chromosome arcs |
trackSelectorType | vestigial: the hierarchical selector is the only one that exists, so this value is ignored. Retained because saved sessions and configs persist it. |
bpPerPx and offsetRadians are the circle's zoom and rotation, the
equivalents of the linear view's bpPerPx/offsetPx; pairing them with
autoFit: false is what stops the first resize refitting over them.
Dotplot view
Example (self-vs-self alignment):
{
"views": [
{
"type": "DotplotView",
"views": [
{
"assembly": "volvox"
},
{
"assembly": "volvox"
}
],
"tracks": ["volvox_fake_synteny"]
}
]
}
Each entry in the views array also accepts an optional loc to navigate that
axis to a specific region (views[0] is the horizontal axis, views[1] the
vertical); omit loc for a whole-genome overview. An entry can also carry
displayedRegionNames, which is a different thing: loc navigates within
what an axis displays, displayedRegionNames changes what it displays at all.
That is what a haplotype-resolved assembly needs: an axis showing the whole
assembly interleaves both haplotypes, and ["*_hap1"] on one axis plots one
haplotype against the reference (globs allowed). It is
applied before autoDiagonalize, so the reorder runs over the restricted set.
{
"views": [
{
"type": "DotplotView",
"views": [
{ "assembly": "volvox", "loc": "ctgA:1-50000" },
{ "assembly": "volvox", "loc": "ctgA:1-50000" }
],
"tracks": ["volvox_fake_synteny"]
}
]
}
Dotplot view properties
The dotplot spec accepts extra top-level fields applied on load:
Launch keys, which name something to do on load rather than state the view holds:
| Launch key | What it does |
|---|---|
autoDiagonalize | After tracks load, automatically run the chromosome diagonalization pass so the bottom/vertical axis follows the top/horizontal axis. The canvas is hidden behind a "Reordering chromosomes…" spinner during the wait, so the user doesn't see an undiagonalized flash. |
colorBy | Initial colorBy. Use 'query' (chromosome painting) for whole-genome views where the default red is hard to distinguish across many ribbons. One of default, strand, query, target, reference, identity, meanQueryIdentity, mappingQuality, dnds, track. |
highlight | loc-strings ("chr1:100-200") or JSON objects matching HighlightType, mirroring LinearGenomeView's init.highlight |
minAlignmentLength | Per-feature alignment-length filter applied at the renderer. Hides chains shorter than this many bp; cuts the genome-scale hairball. |
showColorLegend | Show the floating color-by legend on load. Set false to hide it (e.g. a curated demo/screenshot where the legend would clutter the figure). |
Properties, which are whatever the state model declares and the view restores natively:
| Property | What it does |
|---|---|
alpha | Plot-wide alpha applied to every point. View-level for the same reason lineWidth is: the only control is view-level, so storing it per display meant a track shown after the slider moved rendered at the default while the slider said otherwise. |
assemblyNames | the two assemblies being compared, horizontal axis first. A spec normally names these per axis instead, as views[0].assembly and views[1].assembly. |
displayName | displayName is displayed in the header of the view, or assembly names being used if none is specified |
drawCigar | resolve each alignment's CIGAR into the drawn shape rather than plotting it as a single straight segment |
height | the height of the plot in pixels |
hview | the horizontal axis, as a full 1D view state. A spec writes views[0] instead, which the launcher resolves into this. |
lineWidth | Screen-space line width (CSS pixels) applied to every dotplot display in this view. View-level because the GPU pass renders all displays with one uniform. |
lockAspectRatio | When true, hview and vview are kept at the same bpPerPx so the dotplot stays square. Wheel zoom already preserves the ratio; box-zoom and other independent ops trigger an autorun resync. |
lodMode | Level-of-detail tier override for PIF adapters. 'auto' uses the adapter's bpPerPx threshold; 'fine'/'coarse' force a tier. Stored view-level so all displays render at the same tier and the menu doesn't need to fan out per display. |
minIdentity | Hide alignments whose sequence identity is below this fraction (0-1), enforced per feature in buildLineSegments beside minAlignmentLength. A feature carrying no identity at all is kept at every threshold — the alternative blanks a plot whose adapter simply never reported one. View-level, see alpha. |
minimized | collapse the view to its header bar, keeping it in the session rather than closing it |
showGridlines | carry each axis' ruler ticks across the plot as faint lines, the way LinearGenomeView's gridlines carry its own down over the tracks |
showHighlightChips | pins the interactive highlight chip (link icon + context menu) to every highlight band; off by default, where a band instead reveals its chip while the pointer is in it. This is what a screenshot needs, since nothing hovers in one |
trackColorBy | trackId -> color-by mode for that track alone. Absent means the track follows the view-wide colorBy. |
trackColors | trackId -> explicit color under colorBy: 'track'. Absent means the track takes an automatic slot from the palette. |
trackSelectorType | vestigial: the hierarchical selector is the only one that exists, so this value is ignored. Retained because saved sessions and configs persist it. |
vview | the vertical axis, the counterpart to hview. A spec writes views[1]. |
{
"views": [
{
"type": "DotplotView",
"views": [{ "assembly": "volvox" }, { "assembly": "volvox" }],
"tracks": ["volvox_fake_synteny"],
"colorBy": "strand",
"autoDiagonalize": true
}
]
}
Dotplot highlights
The dotplot view accepts a highlight array in the same way the linear genome
view does (see &highlight=). Each entry is a loc string (or a
URL-encoded HighlightType JSON object with optional color/label). A region
is drawn as a translucent vertical band when its assembly matches the
horizontal axis and as a horizontal band when it matches the vertical axis,
so on a self-vs-self plot it appears on both axes:
{
"views": [
{
"type": "DotplotView",
"views": [
{ "assembly": "volvox", "loc": "ctgA:1-50000" },
{ "assembly": "volvox", "loc": "ctgA:1-50000" }
],
"tracks": ["volvox_fake_synteny"],
"highlight": ["ctgA:5000-15000"]
}
]
}
As with the linear genome view, include assemblyName when the band must be
tied to a specific axis assembly (e.g. a non-self plot); a bare loc string
resolves by refName against whichever axis contains it.
Linear synteny view
A self-self alignment is allowed:
{
"views": [
{
"type": "LinearSyntenyView",
"tracks": ["volvox_fake_synteny"],
"views": [
{
"loc": "ctgA:1-30000",
"assembly": "volvox"
},
{
"loc": "ctgA:1000-31000",
"assembly": "volvox"
}
]
}
]
}
Each entry in views is one genome row, and takes the same keys an
LGV does. displayedRegionNames restricts that row to a
subset of its assembly, with globs allowed — so a
whole-genome synteny view can put one haplotype on each row (["*_MATERNAL"]
above ["*_PATERNAL"]), where a row showing the whole assembly interleaves
both. Use it in place of loc: loc navigates within what a row displays, and
takes precedence.
Linear synteny view properties
The synteny view spec accepts extra top-level fields that set the view's initial display state on load. This opens the same view colored by strand, with curved ribbons and stronger opacity:
{
"views": [
{
"type": "LinearSyntenyView",
"tracks": ["volvox_fake_synteny"],
"colorBy": "strand",
"drawCurves": true,
"alpha": 0.8,
"views": [
{ "loc": "ctgA:1-30000", "assembly": "volvox" },
{ "loc": "ctgA:1000-31000", "assembly": "volvox" }
]
}
]
}
Supported init fields:
Launch keys, which name something to do on load rather than state the view holds:
| Launch key | What it does |
|---|---|
autoDiagonalize | After tracks load, automatically run the chromosome diagonalization pass so the bottom/vertical axis follows the top/horizontal axis. The canvas is hidden behind a "Reordering chromosomes…" spinner during the wait, so the user doesn't see an undiagonalized flash. |
collapseEmptyRows | Open any genome row this init gives no tracks collapsed to its ruler. The "No tracks active / Open track selector" block costs ~90px per row, which on a five-row launch is more of the viewport than the ribbons; a row is one click from expanding again (MiniControls, or the view menu's "Rows" → "Expand all views"). Off by default so an authored session keeps its rows as written — the launch dialog turns it on, and offers a checkbox to not. |
colorBy | Initial colorBy. Use 'query' (chromosome painting) for whole-genome views where the default red is hard to distinguish across many ribbons. One of default, strand, query, target, reference, identity, meanQueryIdentity, mappingQuality, dnds, track. |
levelHeights | Pixel height of each synteny strip, one entry per level. Useful for whole-genome views where the default ~100px is too cramped for the ribbon detail to be readable. |
minAlignmentLength | Per-feature alignment-length filter applied at the renderer. Hides chains shorter than this many bp; cuts the genome-scale hairball. |
sameScale | Put every genome row on one bp/px, the coarsest row's, instead of fitting each to the pane width. The largest genome then fills the frame and the rest are drawn shorter in proportion, so a size difference between rows (polyploidy, a genome duplication) is visible as length rather than hidden by the per-row stretch — and orthologs between two rows line up at the same scale on both. Applied last, after any autoDiagonalize pass. |
showColorLegend | Show the floating color-by legend on load. Set false to hide it (e.g. a curated demo/screenshot where the legend would clutter the figure). |
Properties, which are whatever the state model declares and the view restores natively:
| Property | What it does |
|---|---|
alpha | Per-feature opacity in [0,1]. The default is tuned for dense unfiltered hairballs; a whole-genome view with minAlignmentLength set can use a higher value (~0.4) for stronger color. |
bidirectionalFetch | Ask each level's adapter for the alignments anchored on its LOWER row as well as its upper one. A synteny band queries its query axis — the upper row of the pair — so an alignment anchored on a lower-row contig whose other end is somewhere the upper row is not showing is never requested, and nothing downstream can recover it. Which genome a user stacked on top therefore decided what the view was able to report. A FETCH INPUT, unlike showOffscreenMates above, and off by default because it is a second query per level. |
cigarMode | How per-base insertions and deletions inside each alignment are shown: 'full' paints indel wedges, 'matches' leaves them see-through, 'off' draws blocks only. |
displayName | displayName is displayed in the header of the view, or assembly names being used if none is specified |
drawCurves | Render ribbons as bezier curves rather than straight chords. Reads much better at whole-genome scale, where straight crossings stack into noise. |
drawLocationMarkers | Continue the query view's scalebar grid down through the ribbons: a tick at each round query coordinate, joined to the coordinate the alignment pairs it with. |
fadeThinAlignmentsMode | Whether to fade a sub-pixel-thin ribbon's opacity by its on-screen width (see WIDTH_FADE_FLOOR in syntenyTypes.slang), so an unfiltered whole-genome view doesn't read as a hard full-opacity hairball. 'auto' enables the fade once a display is dominated by sub-pixel ribbons (see autoFadeWidthPx); a genuinely sparse comparison (only a handful of ribbons) keeps full alpha so the fade doesn't wash it out. 'on'/'off' pin it. Resolved view-wide by the fadeThinAlignments getter, so all levels fade together. |
followAnchorIndex | Which genome row drives the others while followSynteny is on. Every other row is placed by mapping this one's window outward one level at a time. Clamped to the views array by reconcileLevels. |
followMatchOrientation | While following, flip a row whose placing alignment runs the other way from the anchor's, so the two pan in the same direction. Off by default: the crossing ribbons are the picture of an inversion, and a row turning round under the reader is the loudest thing one can do. |
followSynteny | Move the non-anchor genome rows to whatever region aligns to the anchor row, re-resolved through the synteny data each time the anchor settles. The synteny-aware alternative to linkViews, which locks the rows in PIXELS and so drifts apart as soon as an indel accumulates — the two are mutually exclusive (see setRowSyncMode). |
levels | One synteny band per adjacent pair of views. Each holds its own track list, which is why the track-selector and add-track widgets address them through trackContainerFor — a level is not a view and cannot be the target of their view reference. |
linkViews | sync scroll and zoom across the genome rows, so panning one pans them all |
lodMode | Level-of-detail tier selection for PIF adapters. 'auto' uses the adapter's bpPerPx threshold; 'fine' forces the per-row CIGAR tier (t/q); 'coarse' forces the no-CIGAR tier (T/Q) when present. |
minimized | collapse the view to its header bar, keeping it in the session rather than closing it |
opacityByIdentity | Fade alignment blocks by per-feature identity (lower identity = more transparent). Orthogonal to colorBy — surfaces identity-dropoff zones without consuming the color channel. |
overdrawPx | pixels beyond the visible viewport edge that synteny lines are still drawn. Effective up to the pan buffer (syntenyPanBufferPx: 2000px, or half the viewport when that is wider) — the worker emits CIGAR detail and location markers only that far, so a larger value draws ribbons whose detail stops partway along them. |
showOffscreenMates | Mark, on the query axis, the alignments whose mate is on a contig the facing row is not displaying — real synteny a ribbon has nowhere to land, which the view otherwise draws nothing for. |
trackColorBy | trackId -> color-by mode for that track alone. Absent means the track follows the view-wide colorBy. |
trackColors | trackId -> explicit color under colorBy: 'track'. Absent means the track takes an automatic slot from the palette. |
trackSelectorType | vestigial: the hierarchical selector is the only one that exists, so this value is ignored. Retained because saved sessions and configs persist it. |
levels is accepted because the view declares it: filling it is what tracks
does — one entry per level — and sizing them is levelHeights, so reach for
levels only to author a band's full state.
Each entry in views is a linear genome view, so besides loc, assembly and
tracks it takes that view's own launch props (trackLabels, colorByCDS,
showAminoAcids, showCenterLine, showHighlightChips), and its tracks
entries take inline display options the same way the
LGV's do — a shorter LGVSyntenyDisplay
height, say.
Linear synteny view (multi-way)
The tracks field is a multidimensional array. Each sub-array corresponds to
the synteny tracks at one level of the multi-way view:
{
"views": [
{
"type": "LinearSyntenyView",
"tracks": [["volvox_ins.paf"], ["volvox_del.paf"]],
"views": [
{ "loc": "ctgA:1-50000", "assembly": "volvox_ins" },
{ "loc": "ctgA:1000-50000", "assembly": "volvox" },
{ "loc": "ctgA:1000-44000", "assembly": "volvox_del" }
]
}
]
}
Breakpoint split view
{
"views": [
{
"type": "BreakpointSplitView",
"views": [
{
"loc": "ctgA:1-5000",
"assembly": "volvox",
"tracks": ["volvox_cram"]
},
{
"loc": "ctgB:1-5000",
"assembly": "volvox",
"tracks": ["volvox_cram"]
}
]
}
]
}
The views array specifies the two (or more) linear genome views that make up
the breakpoint split view. Each view can have its own location, assembly, and
tracks, and each tracks entry takes inline display options the same way the
LGV's do.
Alongside views, the spec accepts every setting the view's menu offers:
| Property | What it does |
|---|---|
displayName | displayName is displayed in the header of the view, or assembly names being used if none is specified |
height | the height of the whole view in pixels, panels and overlay together |
interactiveOverlay | make the alignment squiggles drawn between the panels clickable, rather than a static overlay |
linkViews | sync scroll and zoom across the panels, so panning one pans them all |
minimized | collapse the view to its header bar, keeping it in the session rather than closing it |
showHeader | show the view's own header bar, above the panels' own |
showIntraviewLinks | draw the links whose two ends land in the same panel, as well as the ones that cross between panels |
Spreadsheet view
{
"views": [
{
"type": "SpreadsheetView",
"uri": "test_data/volvox/volvox.filtered.vcf.gz",
"assembly": "volvox"
}
]
}
Launch keys, which name something to do on load rather than state the view holds:
| Launch key | What it does |
|---|---|
assembly | the assembly the sheet's rows are read against. With only this and no uri, the view opens on its import form with that assembly already selected rather than the first one in the config |
fileType | the file's format. Otherwise detected from the extension, falling back to VCF, so name it for a file the extension does not identify |
filterText | search-box text, applied once the file is loaded |
uri | the file to load into the sheet. A spec view is untyped user input, so this can be absent, and the view then opens on the import form |
Properties, which are whatever the state model declares and the view restores natively:
| Property | What it does |
|---|---|
displayName | displayName is displayed in the header of the view, or assembly names being used if none is specified |
height | the height of the sheet in pixels |
hideVerticalResizeHandle | chrome switch, for an embed that sizes the view itself |
minimized | collapse the view to its header bar, keeping it in the session rather than closing it |
fileType is one of VCF, BED, BEDPE or STAR-Fusion — a URL with no
extension needs it, and so does STAR-Fusion output, which has none of its own.
SV inspector
{
"views": [
{
"type": "SvInspectorView",
"uri": "test_data/volvox/volvox.dup.vcf.gz",
"assembly": "volvox"
}
]
}
The circular half draws the rows the spreadsheet half's filter leaves, so
filterText is what makes a chord subset reachable from a link.
Launch keys, which name something to do on load rather than state the view holds:
| Launch key | What it does |
|---|---|
assembly | the assembly both halves are read against. With only this and no uri, the view opens on its import form with that assembly already selected rather than the first one in the config |
fileType | the file's format. Otherwise detected from the extension, falling back to VCF, so name it for a file the extension does not identify |
filterText | search-box text for the spreadsheet half, applied once the file is loaded. The circular half draws the rows it leaves, so this is what makes a chord subset reachable from a link |
uri | the file to load. A spec view is untyped user input, so this can be absent, and the view then opens on the import form |
Properties, which are whatever the state model declares and the view restores natively:
| Property | What it does |
|---|---|
displayName | displayName is displayed in the header of the view, or assembly names being used if none is specified |
height | the height of the whole view in pixels, sheet and circle together |
minimized | collapse the view to its header bar, keeping it in the session rather than closing it |
onlyDisplayRelevantRegionsInCircularView | restrict the circular half to the chromosomes the loaded rows actually touch, instead of drawing an arc for every one in the assembly |
spreadsheetWidthFraction | share of the view's width given to the spreadsheet, the rest goes to the circular view. Persisted so dragging the divider survives both a window resize and a session reload |
Plugin-provided view types
A plugin makes its view launchable from a spec by registering a
LaunchView-<type> extension point.
Once the plugin is loaded (via the config's plugins, a hosted config, or a
session's own sessionPlugins — a spec has no
field of its own for it), a session spec can launch its view by type. Their
spec fields are documented by each plugin:
ProteinView(3D structures) fromjbrowse-plugin-protein3d. Fields such asuniprotId,transcriptId,url, andconnectedVieware documented in the plugin's DEVELOPERS.md. See also the proteins tutorial.MsaView(multiple sequence alignments) fromjbrowse-plugin-msaview. Fields such asmsaFileLocation,treeFileLocation, andconnectedViewIdare documented in the plugin's DEVELOPERS.md.
Tiled views / Workspaces
A spec's layout arranges its views into a tiled workspace, and turns
workspaces mode on by doing so. It is a tree whose every node is one of two
things:
- a panel, carrying a
viewsarray of indices into the spec's ownviews, displayed stacked vertically - a container, carrying a
childrenarray, whosedirectionarranges them"horizontal"(left-right),"vertical"(top-bottom) or"tabs"(one tab group, one child visible at a time)
Containers nest arbitrarily deep.
Horizontal split example
{
"views": [
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgA:1-5000",
"tracks": ["gff3tabix_genes"]
},
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgA:5000-10000",
"tracks": ["gff3tabix_genes"]
},
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgB:1-5000",
"tracks": ["gff3tabix_genes"]
}
],
"layout": {
"direction": "horizontal",
"children": [{ "views": [0, 1] }, { "views": [2] }]
}
}
Views 0 and 1 stack in the left panel, view 2 sits alone on the right.
Custom panel sizes
A panel's size gives its proportion of the split:
{
"views": [
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgA:1-5000",
"tracks": ["gff3tabix_genes"]
},
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgB:1-5000",
"tracks": ["gff3tabix_genes"]
}
],
"layout": {
"direction": "horizontal",
"children": [
{
"views": [0],
"size": 70
},
{
"views": [1],
"size": 30
}
]
}
}
A 70/30 split, the left panel taking 70% of the width.
size works at any depth, so a nested container sizes its own children as
well as taking a share of its parent — see the nested example below.
Size every sibling and the numbers are proportions rather than strict
percentages: 7 and 3 lay out the same as 70 and 30. Leave one bare and
they are read as percentages, because the bare panel takes an equal share of
what the sized ones leave over — 70 beside a bare panel is a 70/30 split, and
7 beside a bare panel is a 7/93 one.
Drag the divider to adjust from there; the position is saved with the session.
Tabbed panels
"direction": "tabs" puts its children in one tab group rather than dividing
the space, so only one panel is visible at a time and the rest are a click away.
Useful when the views are alternatives to each other:
{
"views": [
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgA:1-5000",
"tracks": ["gff3tabix_genes"]
},
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgA:1-5000",
"tracks": ["volvox_sv_test"]
}
],
"layout": {
"direction": "tabs",
"children": [{ "views": [0] }, { "views": [1] }]
}
}
Both panels land in the same tab group; the first is the one shown. Tabs can be renamed by double-clicking them, and dragged out into a split at any time.
A tabs node is the one container whose size does not divide space, so a
size on its children describes nothing, and a container nested inside it has
its views gathered into a single tab. A spec that does either says so in a
notification when it loads. Everywhere else, size and nesting mean what they
say.
Mixing the two is where it gets useful — a fixed reference panel on the left, and a set of tabs to page through on the right:
{
"views": [
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgA:1-5000",
"tracks": ["gff3tabix_genes"]
},
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgA:1-5000",
"tracks": ["volvox_sv_test"]
},
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgB:1-5000",
"tracks": ["gff3tabix_genes"]
}
],
"layout": {
"direction": "horizontal",
"children": [
{ "views": [0] },
{
"direction": "tabs",
"children": [{ "views": [1] }, { "views": [2] }]
}
]
}
}
Complex nested layout example
Containers nested inside containers:
{
"views": [
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgA:1-5000",
"tracks": ["gff3tabix_genes"]
},
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgA:5000-10000",
"tracks": ["gff3tabix_genes"]
},
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgB:1-5000",
"tracks": ["gff3tabix_genes"]
},
{
"type": "LinearGenomeView",
"assembly": "volvox",
"loc": "ctgB:5000-10000",
"tracks": ["gff3tabix_genes"]
}
],
"layout": {
"direction": "horizontal",
"children": [
{
"views": [0, 1],
"size": 60
},
{
"direction": "vertical",
"size": 40,
"children": [
{
"views": [2],
"size": 75
},
{
"views": [3],
"size": 25
}
]
}
]
}
}
Views 0 and 1 stack in the left panel, which takes 60% of the width; the right
40% splits vertically, view 2 taking three quarters of that column and view 3
the rest. The 75/25 is the nested sizing — it divides the right-hand
container's own height, not the window's.
Other session formats
Besides spec-, &session= takes four formats that each carry a session
snapshot rather than instructions for building one.
&session=json-
&session=json- takes a plain JSON snapshot of a session, the same shape
produced by "Export session...".
The Share button's gear icon offers this as "Plaintext JSON": the longest of the three formats, and the one to pick when you want to read what the session contains.
&session=json-{"session":{"id":"xSHu7qGJN","name":"test","sessionPlugins":[{"name":"MsaView","url":"https://unpkg.com/jbrowse-plugin-msaview/dist/jbrowse-plugin-msaview.umd.production.min.js"}]}}
The sessionPlugins array in there loads an extra plugin with the session — see
below.
&session=encoded-
Similar to JSON sessions but uses a URL encoding (base64+gzip), so the URLs look like:
https://jbrowse.org/code/jb2/latest/#session=encoded-eJyNU2FzmkAQ_SvOfaaNIKDyLbFN0xlrTWRqnU4mc8ACm8BB7k6Ndfj...
The "Share" button's gear icon has a "Long URL" option that produces these.
Because the entire session is encoded in the URL, they work without the central
session-sharing system in place — and because that makes the URL long, the Share
button puts it in the fragment rather than the
query string. ?session=encoded- is read the same way.
&session=local-
The local sessions look like this
https://host/jbrowse2/?session=local-Fjphq8kjY
By default, after a session is loaded, it is stored into sessionStorage and IndexedDB, and then the URL bar uses the ?session=local- format to reflect the session ID. Pasting the URL in the same browser tab restores from sessionStorage. Pasting it into a new tab on the same machine restores from IndexedDB.
&session=share-
If you click the "Share" button in the header bar, it will generate a "shareable link" that you can give to other users
https://host/jbrowse2/?session=share-HShsEcnq3i&password=nYzTU
The Share button generates a random encryption key on the client, encrypts the
session, and uploads the encrypted blob — without the key — to an AWS DynamoDB
database. The password is never transmitted to the server: the recipient
downloads the DynamoDB entry and decodes it with the key embedded in the URL, so
the DynamoDB contents cannot be decrypted even by JBrowse administrators.
Behind a firewall that cannot reach the shortener, the gear icon in the Share
dialog switches to "Long URL" mode, which needs no central server. To run your
own shortener instead, set shareURL in config.json.
Are share links reproducible
It depends which of the gear icon's three formats you pick.
The short link (&session=share-<ID>&password=<KEY>) is not. Each click of
Share mints a new random key and uploads a new encrypted blob, so the same view
gives a new <ID>/<KEY> pair every time. The link is by design just a key
into our hosted store.
Long URL and Plaintext JSON are. Both carry the whole session in the link itself - compressed for the first, readable JSON for the second - with no server round-trip and no minted password, so the same view and config produce the same link, and it survives rebuilding or moving your instance. Being long, both go into the URL fragment rather than the query string.
Your config can still break reproducibility. A restored session references
tracks by trackId, so a redeploy that regenerates config.json with different
trackIds leaves the link unable to find those tracks. See
keeping trackIds stable.
Loading a plugin from a URL
A snapshot's sessionPlugins array is the only way to name a plugin in the URL
itself; anything else comes from the config JBrowse loads. It takes the same
definitions a config's plugins array takes, and works in all four formats
above — json-, encoded-, share- and local-. A plugin loaded this way
belongs to that session rather than being installed for the user, and travels
with it through the Share button.
Four things govern one written by hand:
nameis required for a UMD bundle — the.umd.production.min.jsbuilds the plugin store publishes. The loader resolves the bundle as the globalJBrowsePlugin<Name>, so a definition carrying only aurlloads the script and then finds nothing in it.- An unrecognized plugin prompts the visitor. Anything not served from
https://jbrowse.org/plugins/and not listed in the plugin store opens a "this session has the following unknown plugins" dialog, naming each one, before the session loads — a plugin is arbitrary javascript running with the page's privileges, and a session URL arrives from whoever sent it. Accepting can remember that url for this origin. A config'spluginsare gated the same way, but only when the config is cross-origin, which is why a config served beside JBrowse never prompts. - A JSON session is state, not spec shorthand. Opening a plugin's view type this way means writing that view's real snapshot rather than the flat spec arguments its launcher takes. Build the session in the app and copy it out of Share → gear → "Plaintext JSON".
- These URLs get long. Put the session
in the fragment to stay under the
request-line limit that answers a long query string with HTTP 414 — and note
that a fragment containing
=makes JBrowse ignore the query string altogether, so?config=…#session=json-…loads the defaultconfig.json, not the named one. Moveconfig=into the fragment as well.
For everyone opening a config to have the plugin, put it in that config's own
plugins array. sessionPlugins is for one session, or one link.