Allow customization on homepage and footer#922
Conversation
There was a problem hiding this comment.
Pull request overview
This pull request makes the homepage and footer customizable by introducing runtime configuration options for organization-specific branding. Previously, the application had hard-coded references to "Harvard Dataverse" and Harvard-specific URLs, making it unsuitable for deployment by other organizations. The changes introduce three new optional configuration sections (branding, homepage, and footer) that allow organizations to customize the dataverse name, support URL, copyright holder, and privacy policy URL without rebuilding the application.
Changes:
- Added runtime configuration schema for branding, homepage, and footer customization in
src/config.ts - Updated Footer component to use configurable copyright holder and privacy policy URL
- Updated Usage component to use configurable dataverse name and support URL
- Modified translation strings to use interpolation for dynamic branding values
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/config.ts | Added zod schema definitions for optional branding, homepage, and footer configuration objects |
| src/sections/layout/footer/Footer.tsx | Updated to use configurable copyrightHolder and privacyPolicyUrl from app config with proper fallbacks and optional chaining |
| src/sections/homepage/usage/Usage.tsx | Modified to use configurable dataverseName and supportUrl from app config (has critical issues with null safety) |
| public/config.js | Added default configuration values for branding, homepage, and footer sections with Harvard-specific defaults |
| cypress.config.ts | Added test configuration values for branding, homepage, and footer sections |
| tests/support/bootstrapAppConfig.ts | Extended test config builder to support new branding, homepage, and footer configuration |
| tests/component/sections/layout/footer/Footer.spec.tsx | Added test coverage for privacy policy link and updated repository interface to match expanded API |
| public/locales/en/homepage.json | Changed hard-coded "Harvard Dataverse" strings to use {{dataverseName}} interpolation |
| public/locales/es/homepage.json | Changed hard-coded "Harvard Dataverse" strings to use {{dataverseName}} interpolation |
| public/locales/en/footer.json | Updated copyright translation to use {{copyrightHolder}} interpolation |
| public/locales/es/footer.json | Updated copyright translation to use {{copyrightHolder}} interpolation |
| CHANGELOG.md | Added entry documenting the new runtime configuration options |
Comments suppressed due to low confidence (1)
src/sections/homepage/usage/Usage.tsx:89
- The Usage component now uses configurable branding values (dataverseName, supportUrl) but lacks test coverage. Other homepage components like Metrics and SearchInput have dedicated test files in tests/component/sections/homepage/. Consider adding tests to verify that: 1) the dataverseName interpolation works correctly in the translation strings, 2) the supportUrl is properly used in the link, 3) fallback behavior works when branding config is not provided, and 4) the component handles undefined branding/homepage config objects gracefully.
export const Usage = ({ collectionId }: UsageProps) => {
const { t } = useTranslation('homepage', { keyPrefix: 'usage' })
const appConfig = requireAppConfig() as AppConfig
const dataverseName = appConfig.branding.dataverseName ?? 'Dataverse'
const supportUrl = appConfig.homepage.supportUrl
return (
<Row>
<Col xs={12} lg={4} className={styles.column_card}>
<Card className={styles.card}>
<Card.Body className={styles.card_body}>
<h5>{t('datasets.title')}</h5>
<p className="small text-muted">{t('datasets.content')}</p>
<footer className={styles.footer_wrapper}>
<Link
to={RouteWithParams.CREATE_DATASET(collectionId)}
className="btn btn-secondary btn-sm">
<Stack direction="horizontal" gap={1}>
<span className={styles.cta_link_text}>{t('datasets.text_button')}</span>{' '}
<Plus size={22} />
</Stack>
</Link>
</footer>
</Card.Body>
</Card>
</Col>
<Col xs={12} lg={4} className={styles.column_card}>
<Card className={styles.card}>
<Card.Body className={styles.card_body}>
<h5>{t('collections.title')}</h5>
<p className="small text-muted">{t('collections.content')}</p>
<footer className={styles.footer_wrapper}>
<Link
to={RouteWithParams.CREATE_COLLECTION(collectionId)}
className="btn btn-secondary btn-sm">
<Stack direction="horizontal" gap={1}>
<span className={styles.cta_link_text}>{t('collections.text_button')}</span>{' '}
<Plus size={22} />
</Stack>
</Link>
</footer>
</Card.Body>
</Card>
</Col>
<Col xs={12} lg={4} className={styles.column_card}>
<Card className={styles.card}>
<Card.Body className={styles.card_body}>
<h5>{t('general.title', { dataverseName })}</h5>
<p className="small text-muted">{t('general.content')}</p>
<footer className={styles.footer_wrapper}>
<a
href={supportUrl}
target="_blank"
rel="noreferrer noopener"
className="btn btn-secondary btn-sm">
<Stack direction="horizontal" gap={2}>
<span className={styles.cta_link_text}>{t('general.text_button')}</span>
<BoxArrowUpRight size={14} />
</Stack>
</a>
</footer>
</Card.Body>
</Card>
</Col>
</Row>
)
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…emove-harvard-specific-content
What this PR does / why we need it:
The homepage displays 'Harvard’ as name of the archive and has links to the Harvard support page.
Which issue(s) this PR closes:
Special notes for your reviewer:
There is a test failing due to test coverage
Suggestions on how to test this:
Check if there are any "Harvard" related text on the page
Does this PR introduce a user interface change? If mockups are available, please link/include them here:
Is there a release notes or changelog update needed for this change?:
Yes
Additional documentation: