Created Injecting code to UT Pages (markdown)

2025-06-15 20:17:06 -05:00
parent b3174d9341
commit b24df00d57

@@ -0,0 +1,85 @@
# Code Injection Guide
This page documents how we inject code into supported pages across the UT Austin web ecosystem.
# Choosing a page to inject on
Current URL is obtained through `window.location.href`
## siteSupport
Contains enum to determine what page a user is on. For example
```ts
if (url.includes('my.utexas.edu/student/student/index') || url.includes('my.utexas.edu/student/')) {
return SiteSupport.MY_UT;
}
```
## renderComponent
Found in `index.tsx`, the `renderComponent` function is a utility used by the extension to inject React components into websites (and other supported pages). It creates a new div and appends it to the document body. It then uses Reacts createRoot to render the React component inside this container.
```ts
const renderComponent = (Component: React.ComponentType) => {
const container = document.createElement('div');
container.id = 'extension-root';
document.body.appendChild(container);
createRoot(container).render(
<React.StrictMode>
<Component />
</React.StrictMode>
);
};
```
After a site is determined, components are rendered in `index.tsx`. For example
```ts
if (support === SiteSupport.COURSE_CATALOG_DETAILS || support === SiteSupport.COURSE_CATALOG_LIST) {
renderComponent(() => <CourseCatalogMain support={support} />);
}
if (support === SiteSupport.MY_UT) {
renderComponent(InjectedButton);
}
if (support === SiteSupport.COURSE_CATALOG_SEARCH) {
renderComponent(DaysCheckbox);
}
```
# Examples
## CourseCatalogMain
Relevant page:
![image](https://github.com/user-attachments/assets/21645b97-8b8e-46db-b756-12c3d7fc870a)
`<ExtensionRoot>` used to prevent the native page styles from being overridden with our own.
```ts
return (
<ExtensionRoot>
<NewSearchLink />
<RecruitmentBanner />
<TableHead>Plus</TableHead>
{rows.map(
row =>
row.course && (
<TableRow
key={row.course.uniqueId}
row={row}
isSelected={row.course.uniqueId === selectedCourse?.uniqueId}
activeSchedule={activeSchedule}
onClick={handleRowButtonClick(row.course)}
/>
)
)}
<CourseCatalogInjectedPopup
course={selectedCourse!} // always defined when showPopup is true
show={showPopup}
onClose={() => setShowPopup(false)}
afterLeave={() => setSelectedCourse(null)}
/>
{enableScrollToLoad && <AutoLoad addRows={addRows} />}
</ExtensionRoot>
);
```