TrackedLinkContext
HOC wrapping the given Component
in a LinkContext, enriching it with the objectiv
prop and automatically tracking PressEvent on onClick.
TrackedLinkContext: <T>(props: T & {
objectiv: {
Component: ElementType | keyof ReactHTML,
id?: string,
href?: string,
waitUntilTracked?: boolean,
normalizeId?: boolean,
}
}) => JSX.Element
objectiv
prop attributes
type | default value | ||
---|---|---|---|
required | Component | ElementType | keyof ReactHTML | |
optional | id | string | inferred from native id , title or children |
optional | href | string | inferred from native href |
optional | waitUntilTracked | boolean | false |
optional | normalizeId | boolean | true |
- When the
id
attribute is omitted, we attempt to infer it from one of the anchor's native props:id
,title
,children
. - When the
href
attribute is omitted, we attempt to infer it from the anchor'shref
prop.
If either fails, an error will be logged to the Developer Console and the original Component is rendered.
Returns
JSX.Element
Automatic Events
- PressEvent on
onClick
.
Usage example
Elements
A plain anchor tag. TrackedLinkContext will auto-detect href
from the native attribute and id
from children
.
import { TrackedLinkContext } from '@objectiv/tracker-react';
<TrackedLinkContext<ComponentProps<'a'>>
href={'/privacy'}
objectiv={{
Component: 'a'
}}
>
Privacy
</TrackedLinkContext>
When inferring an identifier from children
is not possible, TrackedLinkContext will look at title
or id
.
import { TrackedLinkContext } from '@objectiv/tracker-react';
<TrackedLinkContext<ComponentProps<'a'>>
href={'/privacy'}
title={'privacy'}
objectiv={{
Component: 'a'
}}
>
<img src="/lock.jpg"/>
</TrackedLinkContext>
<TrackedLinkContext<ComponentProps<'a'>>
href={'/privacy'}
id={'privacy'}
objectiv={{
Component: 'a'
}}
>
<img src="/lock.jpg"/>
</TrackedLinkContext>
When none of the above attributes is present, either id
, href
, or both can be manually specified via the objectiv
prop.
import { TrackedLinkContext } from '@objectiv/tracker-react';
<TrackedLinkContext<ComponentProps<'a'>>
href={'#'}
objectiv={{
Component: 'a',
id: 'privacy',
href: '/privacy'
}}
>
<img src="/lock.jpg"/>
</TrackedLinkContext>
ID normalization
By default, all Tracked Context Components automatically normalize their Context identifiers to a kebab-cased format.
This can be disabled via the normalizeId
option. This is useful when identifiers need to be preserved for cross-platform
concerns or if they are standardized identifiers, e.g. a code from a backend API.
In this example the identifier, which would normally be privacy-policy
, will be preserved as Privacy Policy
:
import { TrackedLinkContext } from '@objectiv/tracker-react';
<TrackedLinkContext<ComponentProps<'a'>>
href={'/privacy'}
objectiv={{
Component: 'a',
normalizeId: false
}}
>
Privacy Policy
</TrackedLinkContext>
The same happens when the identifier is inferred from the title
or id
attributes:
import { TrackedLinkContext } from '@objectiv/tracker-react';
<TrackedLinkContext<ComponentProps<'a'>>
href={'/privacy'}
title={'Privacy Policy'}
objectiv={{
Component: 'a',
normalizeId: false
}}
>
<img src="/lock.jpg"/>
</TrackedLinkContext>
<TrackedLinkContext<ComponentProps<'a'>>
href={'/privacy'}
id={'Privacy Policy'}
objectiv={{
Component: 'a',
normalizeId: false
}}
>
<img src="/lock.jpg"/>
</TrackedLinkContext>
Components
The Component
prop doesn't need to be a JSX Element. Actually, more often than not, it will probably be another Component.
Here is an example of how to wrap around a React Router Link.
import { Link, useHref } from "react-router-dom";
import { TrackedLinkContext } from '@objectiv/tracker-react';
const href = useHref(props.to);
<TrackedLinkContext<ComponentProps<typeof Link>>
{...props}
ref={ref}
objectiv={{
Component: Link,
href
}}
/>
And here is the full, more general purpose, version of the same Component with an ad-hoc objectiv
prop:
import { TrackedLinkContext, TrackedLinkContextObjectivProp } from '@objectiv/tracker-react';
import React, { ComponentProps } from 'react';
import { Link, LinkProps, useHref } from 'react-router-dom';
export type TrackedLinkProps = LinkProps & {
objectiv?: Omit<TrackedLinkContextObjectivProp, 'Component' | 'href'>;
};
export const TrackedLink = React.forwardRef<HTMLAnchorElement, TrackedLinkProps>(
({ objectiv, ...nativeProps }, ref) => (
<TrackedLinkContext<ComponentProps<typeof Link>>
{...nativeProps}
ref={ref}
objectiv={{
...objectiv,
Component: Link,
href: useHref(nativeProps.to),
waitUntilTracked: objectiv?.waitUntilTracked ?? nativeProps.reloadDocument,
}}
/>
)
);
You can now use TrackedLink exactly as you would with the original Link component:
<TrackedLink to={'/home'} />
<TrackedLink to={'/home'} objectiv={{ id: 'hero-id' }}>
<TrackedLink to={'/home'} id={'hero-id'}>
Check these how-to guides for more thorough examples:
TrackedLinkContext
internally uses LinkContextWrapper.