@autobusal/common 1.7.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BlogItem/Image.tsx +6 -2
- package/CHANGELOG.md +26 -0
- package/CompanyItem/CompanyItem.tsx +2 -2
- package/Meta.tsx +28 -0
- package/RouteItem/RouteItem.tsx +1 -1
- package/package.json +1 -1
package/BlogItem/Image.tsx
CHANGED
|
@@ -8,16 +8,20 @@ interface Props {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
const Image = ({ type, internal, image_url, title }: Props): JSX.Element => {
|
|
11
|
+
// preview/short are grid/sidebar thumbnails - often several per page,
|
|
12
|
+
// frequently below the fold, so they're deferred. type="view" is the
|
|
13
|
+
// single article's own hero image, likely this page's LCP element, so it
|
|
14
|
+
// loads eagerly at high priority instead.
|
|
11
15
|
if (type === 'preview' || type === 'short') {
|
|
12
16
|
return (
|
|
13
17
|
<ImageLink to={ `/blog/article/${ internal }` }>
|
|
14
|
-
<ContainerImage src={ image_url } alt={ title } />
|
|
18
|
+
<ContainerImage src={ image_url } alt={ title } loading="lazy" decoding="async" />
|
|
15
19
|
</ImageLink>
|
|
16
20
|
);
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
return (
|
|
20
|
-
<ContainerImage src={ image_url } alt={ title } />
|
|
24
|
+
<ContainerImage src={ image_url } alt={ title } loading="eager" fetchPriority="high" />
|
|
21
25
|
);
|
|
22
26
|
};
|
|
23
27
|
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,32 @@
|
|
|
3
3
|
All notable changes to `@autobusal/common` are documented here. This project follows
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/) and [Semantic Versioning](https://semver.org/).
|
|
5
5
|
|
|
6
|
+
## [1.8.1] - 2026-07-30
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- **Added `loading="lazy" decoding="async"` to below-the-fold list images**
|
|
11
|
+
(`BlogItem/Image.tsx` preview/short thumbnails, `CompanyItem.tsx`,
|
|
12
|
+
`RouteItem.tsx` operator logos) - none had lazy loading, so a search
|
|
13
|
+
results page or operator/agent listing loaded every logo eagerly
|
|
14
|
+
regardless of position. `BlogItem/Image.tsx`'s `type="view"` (the single
|
|
15
|
+
article's own hero image, likely that page's LCP element) instead gets
|
|
16
|
+
`loading="eager" fetchPriority="high"`.
|
|
17
|
+
|
|
18
|
+
## [1.8.0] - 2026-07-30
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- **GA4 SPA pageview tracking in `Meta`.** gtag.js only auto-sends a
|
|
23
|
+
page_view on its initial `config` call - every client-side route change
|
|
24
|
+
was invisible to analytics (pairs with `@autobusal/providers` 1.6.2, which
|
|
25
|
+
disables the automatic one). Meta now sends an explicit pageview
|
|
26
|
+
(`location.pathname + location.search`, current title) whenever the path
|
|
27
|
+
changes, since it's already rendered on nearly every real page. Excluded
|
|
28
|
+
from the effect's dependencies on purpose: a title-only change (e.g. a
|
|
29
|
+
language switch) does not fire a new pageview, only an actual navigation
|
|
30
|
+
does.
|
|
31
|
+
|
|
6
32
|
## [1.7.0] - 2026-07-30
|
|
7
33
|
|
|
8
34
|
### Added
|
|
@@ -16,12 +16,12 @@ const CompanyItem = ({ item, type }: Props): JSX.Element => {
|
|
|
16
16
|
{ type === 'operator'
|
|
17
17
|
? (
|
|
18
18
|
<LinkLogo to={ item.link }>
|
|
19
|
-
<img src={ item.logo_url } alt={ item.company } />
|
|
19
|
+
<img src={ item.logo_url } alt={ item.company } loading="lazy" decoding="async" />
|
|
20
20
|
</LinkLogo>
|
|
21
21
|
)
|
|
22
22
|
: (
|
|
23
23
|
<ContainerLogo>
|
|
24
|
-
<img src={ item.logo_url } alt={ item.company } />
|
|
24
|
+
<img src={ item.logo_url } alt={ item.company } loading="lazy" decoding="async" />
|
|
25
25
|
</ContainerLogo>
|
|
26
26
|
) }
|
|
27
27
|
|
package/Meta.tsx
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
import { useLocation } from 'react-router-dom';
|
|
3
|
+
import ReactGA from 'react-ga4';
|
|
4
|
+
import { useGetSettings } from '@autobusal/providers/services';
|
|
3
5
|
|
|
4
6
|
interface Props {
|
|
5
7
|
title: string
|
|
@@ -70,11 +72,37 @@ const useCanonicalUrl = (explicit?: string): string => {
|
|
|
70
72
|
return explicit ?? `${ window.location.origin }${ location.pathname }`;
|
|
71
73
|
};
|
|
72
74
|
|
|
75
|
+
// GA4's gtag.js only auto-sends a page_view on its initial `config` call
|
|
76
|
+
// (see providers/Setup/analytics.ts, which disables that and initializes
|
|
77
|
+
// with send_page_view: false) - every client-side route change in this SPA
|
|
78
|
+
// was otherwise invisible to analytics. Meta is the one component rendered
|
|
79
|
+
// on nearly every real page (136 call sites across both apps), already
|
|
80
|
+
// tracks the canonical path via useLocation, and mounts fresh on every
|
|
81
|
+
// navigation - the natural place to fire the pageview React Router itself
|
|
82
|
+
// doesn't have a dedicated hook for. The 2-3 truly Meta-less pages (a
|
|
83
|
+
// redirect-only auth callback, an invalid-signature bounce) aren't
|
|
84
|
+
// meaningful page views anyway.
|
|
85
|
+
const usePageviewTracking = (path: string, title: string): void => {
|
|
86
|
+
const { data: settings } = useGetSettings();
|
|
87
|
+
const gaId = settings.preferences.googleAnalyticsID;
|
|
88
|
+
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
if (gaId === null) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
ReactGA.send({ hitType: 'pageview', page: path, title });
|
|
95
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
96
|
+
}, [gaId, path]);
|
|
97
|
+
};
|
|
98
|
+
|
|
73
99
|
const Meta = ({ title, keywords, description, image, url, type = 'website', noIndex = false, children }: Props): JSX.Element => {
|
|
74
100
|
const fullTitle = withBrand(title);
|
|
75
101
|
const canonicalUrl = useCanonicalUrl(url);
|
|
102
|
+
const location = useLocation();
|
|
76
103
|
|
|
77
104
|
useSoleTitleOwnership(fullTitle);
|
|
105
|
+
usePageviewTracking(location.pathname + location.search, fullTitle);
|
|
78
106
|
|
|
79
107
|
return (
|
|
80
108
|
<>
|
package/RouteItem/RouteItem.tsx
CHANGED
|
@@ -21,7 +21,7 @@ const RouteItem = ({ type, route, t }: Props): JSX.Element => {
|
|
|
21
21
|
<About>
|
|
22
22
|
<Image>
|
|
23
23
|
<Logo to={ route.operator.link }>
|
|
24
|
-
<img src={ route.operator.logo_url } alt={ route.operator.company } />
|
|
24
|
+
<img src={ route.operator.logo_url } alt={ route.operator.company } loading="lazy" decoding="async" />
|
|
25
25
|
</Logo>
|
|
26
26
|
</Image>
|
|
27
27
|
|