Alt description missing in image

Universal Link component

If you import the Link component from @green-stack/navigation, it will automatically use the correct navigation system for the platform you are on.

import { Link } from '@green-stack/navigation'

However, you can also import it from @app/primitives to apply tailwind styles:

import { Link } from '@app/primitives'

You can use the href prop to navigate to a new page:

<Link
    className="text-link p-2 rounded"
    href="/examples/[slug]"
>
    See example
</Link>

UniversalLinkProps

PropertyTypeDescription
childrenReact.ReactNodeThe content to be rendered inside the link.
hrefstring | HREFThe path to route to on web or mobile. String only. Hints for internal routes provided through codegen.
styleStyle prop: https://reactnative.dev/docs/text#style
classNamestringNativewind classNames should be applied to either the parent or children of Link. Ideally, create or use a TextLink component instead.
replacebooleanShould replace the current route without adding to the history - Default: false.
onPressExtra handler that fires when the link is pressed.
targetSpecifies where to display the linked URL.
asChildbooleanMobile only - Forward props to child component. Useful for custom buttons - Default: false.
pushbooleanMobile only - Should push the current route, always adding to the history - Default: true.
testIDstring | undefinedMobile only - Used to locate this view in end-to-end tests.
nativeIDstring | undefinedMobile only - Used to reference react managed views from native code. @deprecated use id instead.
idstring | undefinedMobile only - Used to reference react managed views from native code.
allowFontScalingMobile only - Specifies whether fonts should scale to respect Text Size accessibility settings.
numberOfLinesMobile only - Specifies the maximum number of lines to use for rendering text.
maxFontSizeMultiplierMobile only - Specifies the maximum scale factor for text.
suppressHighlightingMobile only - When true, no visual change is made when text is pressed down.
scrollbooleanWeb only - Whether to override the default scroll behavior - Default: false.
shallowbooleanWeb only - Update the path of the current page without rerunning getStaticProps, getServerSideProps or getInitialProps - Default: false.
passHrefbooleanWeb only - Forces Link to send the href property to its child - Default: false.
prefetchbooleanWeb only - Prefetch the page in the background. Any <Link /> that is in the viewport (initially or through scroll) will be preloaded. Prefetch can be disabled by passing prefetch={false}. When prefetch is set to false, prefetching will still occur on hover. Pages using Static Generation will preload JSON files with the data for faster page transitions. Prefetching is only enabled in production. - Default: true
localestring | falseWeb only - The active locale is automatically prepended. locale allows for providing a different locale. When false href has to include the locale as the default behavior is disabled.
asUrl | undefinedWeb only - Optional decorator for the path that will be shown in the browser URL bar.

React Portability Patterns

Each environment has it’s own optimized Link component. This is why there are also versions specifically for each of those environments:

        • Link.expo.tsx
        • Link.next.tsx
        • Link.tsx
        • Link.types.ts
  • Link.next.tsx is optimized for the Next.js app router.
  • Link.expo.tsx is optimized for Expo Router.
  • Link.types.ts ensures both implementations are compatible with the same interface, allowing you to use the same Link component across both Expo and Next.js environments.

The main Link.tsx retrieves whichever implementation was provided as contextLink to the <UniversalAppProviders> component, which is further passed to <CoreContext.Provider/>:

ExpoRootLayout.tsx
import { Link as ExpoLink } from '@green-stack/navigation/Link.expo'
 
// ... Later ...
 
<UniversalAppProviders
    contextLink={ExpoLink}
>
    ...
</UniversalAppProviders>
NextRootLayout.tsx
import { Link as NextLink } from '@green-stack/navigation/Link.next'
 
// ... Later ...
 
<UniversalAppProviders
    contextLink={NextLink}
>
    ...
</UniversalAppProviders>

Why this pattern?

The ‘React Portability Patterns’ used here are designed to ensure that you can easily reuse optimized versions of components across different flavours of writing React.

On the one hand, that means it’s already set up to work with both Expo and Next.js in an optimal way.

But, you can actually add your own implementations for other environments, without having to refactor the code that uses the Link component.

Supporting more environments

Just add your own Link.<environment>.tsx file that respects the shared types, and then pass it to the <UniversalAppProviders> component as contextLink.