Skip to content

Commit

Permalink
fix: ensure that builtwithfern is not hidden using custom css (#1962)
Browse files Browse the repository at this point in the history
  • Loading branch information
abvthecity authored Jan 8, 2025
1 parent b673fdc commit 271e6c4
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 23 deletions.
9 changes: 3 additions & 6 deletions packages/fern-docs/components/src/BuiltWithFern.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,7 @@ export const BuiltWithFern = forwardRef<HTMLAnchorElement, BuiltWithFernProps>(

return (
<FernTooltipProvider>
<FernTooltip
content={BUILT_WITH_FERN_TOOLTIP_CONTENT}
side="top"
asChild
>
<FernTooltip content={BUILT_WITH_FERN_TOOLTIP_CONTENT} side="top">
<a
ref={ref}
{...props}
Expand All @@ -61,7 +57,8 @@ export const BuiltWithFern = forwardRef<HTMLAnchorElement, BuiltWithFernProps>(
</span>
<FernLogo
fill={isHovering ? FernLogoFill.Default : FernLogoFill.Muted}
className="-mt-0.5 h-3.5 transition"
className="transition"
style={{ height: 14, marginTop: -2 }}
/>
</a>
</FernTooltip>
Expand Down
20 changes: 14 additions & 6 deletions packages/fern-docs/components/src/FernLogo.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import clsx from "clsx";
import { ComponentPropsWithoutRef, forwardRef } from "react";

export enum FernLogoFill {
/**
Expand Down Expand Up @@ -49,16 +50,21 @@ export declare namespace FernLogo {
}
}

export const FernLogo: React.FC<FernLogo.Props> = ({
fill = FernLogoFill.Default,
className,
}) => {
export const FernLogo = forwardRef<
SVGSVGElement,
ComponentPropsWithoutRef<"svg"> & { fill?: FernLogoFill }
>(({ fill = FernLogoFill.Default, ...props }, ref) => {
return (
<svg
ref={ref}
viewBox="0 0 604 164"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={clsx("aspect-[604/164]", className)}
{...props}
style={{
aspectRatio: "604/164",
...props.style,
}}
>
<path
fillRule="evenodd"
Expand Down Expand Up @@ -91,4 +97,6 @@ export const FernLogo: React.FC<FernLogo.Props> = ({
/>
</svg>
);
};
});

FernLogo.displayName = "FernLogo";
2 changes: 1 addition & 1 deletion packages/fern-docs/ui/src/layouts/GuideLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ export function GuideLayout({
</div>

{!hideNavLinks && <BottomNavigationNeighbors />}
<BuiltWithFern className="mx-auto my-8 w-fit" />
</footer>
)}
<BuiltWithFern className="mx-auto my-8 w-fit" />
</article>
</main>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/fern-docs/ui/src/layouts/OverviewLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ export function OverviewLayout({
<div>{!hideFeedback && <Feedback />}</div>
<EditThisPageButton editThisPageUrl={editThisPageUrl} />
</div>
<BuiltWithFern className="mx-auto my-8 w-fit" />
</footer>
)}
<BuiltWithFern className="mx-auto my-8 w-fit" />
</article>
</main>
);
Expand Down
2 changes: 1 addition & 1 deletion packages/fern-docs/ui/src/layouts/PageLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ export function PageLayout({
<div>{!hideFeedback && <Feedback />}</div>
<EditThisPageButton editThisPageUrl={editThisPageUrl} />
</div>
<BuiltWithFern className="mx-auto my-8 w-fit" />
</footer>
)}
<BuiltWithFern className="mx-auto my-8 w-fit" />
</main>
);
}
2 changes: 1 addition & 1 deletion packages/fern-docs/ui/src/layouts/ReferenceLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ export function ReferenceLayout({
<div>{!hideFeedback && <Feedback />}</div>
<EditThisPageButton editThisPageUrl={editThisPageUrl} />
</div>
<BuiltWithFern className="mx-auto my-8 w-fit" />
</footer>
)}
<BuiltWithFern className="mx-auto my-8 w-fit" />
</article>
</div>
</main>
Expand Down
86 changes: 79 additions & 7 deletions packages/fern-docs/ui/src/sidebar/BuiltWithFern.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BuiltWithFern as BuiltWithFernComponent } from "@fern-docs/components";
import { createContext, useContext } from "react";
import { createContext, useContext, useEffect, useRef } from "react";
import { trackInternal } from "../analytics";
import { useDomain, useFeatureFlag } from "../atoms";

export const BuiltWithFern: React.FC<{ className?: string }> = ({
Expand All @@ -8,19 +9,90 @@ export const BuiltWithFern: React.FC<{ className?: string }> = ({
const domain = useDomain();
const isWhitelabeled = useFeatureFlag("isWhitelabeled");
const hideBuiltWithFern = useContext(HideBuiltWithFernContext);
const component = useRef<HTMLAnchorElement>(null);

if (isWhitelabeled || hideBuiltWithFern) {
return null;
}

/**
* if the docs is not whitelabeled, the following ensures that builtwithfern is not removed from the DOM:
* - we'll use a inline <style> tag to ensure that the !important rules are applied and cannot be overridden using custom CSS
* - then, we'll use a setTimeout to check if builtwithfern is visible 15 seconds after it's mounted
* - and if it's not visible, we'll emit an internal event: "builtwithfern_removed"
*/
return (
<BuiltWithFernComponent
utmCampaign="buildWith"
utmMedium="docs"
utmSource={domain}
className={className}
/>
<>
<style>
{`
#builtwithfern {
display: flex !important;
opacity: 100% !important;
}
#builtwithfern * {
display: initial !important;
width: unset !important;
opacity: 100% !important;
}
#builtwithfern,
#builtwithfern * {
visibility: initial !important;
overflow: visible !important;
position: relative !important;
left: unset !important;
top: unset !important;
right: unset !important;
bottom: unset !important;
inset: unset !important;
}`}
</style>
<BuiltWithFernComponent
ref={component}
id="builtwithfern"
utmCampaign="buildWith"
utmMedium="docs"
utmSource={domain}
className={className}
/>
<BuiltWithFernWatcher component={component} />
</>
);
};

function BuiltWithFernWatcher({
component,
}: {
component: React.RefObject<HTMLAnchorElement>;
}) {
useEffect(() => {
const checkVisibility = () => {
const el = component.current;
const { width, height } = el?.getBoundingClientRect() ?? {};
if (
el == null || // builtwithfern is not mounted
!document.body.contains(el) || // builtwithfern is not in the DOM
el.offsetParent == null || // builtwithfern is not visible
!width ||
width < 50 ||
!height ||
height < 10
) {
// send alert to fern that builtwithfern was removed from the DOM
trackInternal("builtwithfern_removed");

if (process.env.NODE_ENV === "development") {
console.debug("builtwithfern is not visible");
}
}
};

const intervalId = window.setTimeout(checkVisibility, 15_000);
return () => window.clearTimeout(intervalId);
}, [component]);

return false;
}

export const HideBuiltWithFernContext = createContext(false);

0 comments on commit 271e6c4

Please sign in to comment.