A professional, interactive dashboard for visualizing Real World Data (RWD) Working Group data from Google Sheets, built with Quarto and R, and automatically deployed to GitHub Pages.
- Real-time Data Loading: Fetches data directly from public Google Sheets on each page visit
- Interactive Visualizations: Beautiful, interactive charts powered by Plotly
- Structured Data Entry: Browser-based submission form with validation and optional Google Apps Script writeback
- Professional Design: Modern, responsive UI with custom theming
- Automated Deployment: GitHub Actions automatically builds and deploys to GitHub Pages
- Zero Maintenance: No server required - fully static site hosted on GitHub Pages
To work with this project locally, you'll need:
# Clone the repository
git clone <your-repo-url>
cd rwd_wg
# Check dependencies and install R packages
make check-deps
make installUsing Make: This project includes a
Makefilefor convenience. Runmake helpto see all available commands.
- Create or prepare your Google Sheet with data
- Set sharing to "Anyone with the link can view" (for public access)
- Copy the full URL of your Google Sheet
- Open
index.qmdand replaceYOUR_GOOGLE_SHEET_URL_HEREwith your sheet URL
# In index.qmd, around line 30:
SHEET_URL <- "https://docs.google.com/spreadsheets/d/YOUR_SHEET_ID/edit"The submit.qmd page can write new entries to the Inventory tab through a Google Apps Script Web App.
- Open your Google Sheet and create an
Optionstab (recommended) with one column per dropdown list:TypeTopicRWD TypeIntended AudienceArtifacts IncludedAvailabilityCredentials Offered
- Seed options in one of two ways:
- Import
data/options_template.csvinto theOptionstab (recommended baseline from current inventory values), or - Enter your own allowed values under each header column.
- Import
- Create a new Apps Script project from the same sheet and paste in
apps_script/Code.gs. - Add these metadata headers to row 2 of the
Inventorysheet (you can hide these columns):Meta Created AtMeta Updated AtMeta SourceMeta URL StatusMeta URL Checked AtMeta URL Check DetailThe script writes only to these metadata columns and does not overwrite inventory data columns.
- Deploy as a Web App:
- Execute as:
Me - Who has access:
Anyone(or your preferred allowed audience)
- Execute as:
- Set
defaultSubmitUrlinsubmit.qmdto your Web App/execURL. - Optional smoke test: open the
/execURL in a browser and confirm it returns JSON withok: true. - Configure submission token (required for hardened submit endpoint):
- In Apps Script:
Project Settings->Script properties-> addSUBMIT_TOKEN. - In GitHub repo secrets: add
SUBMIT_TOKENwith the same value. - For local rendering: set env var
SUBMIT_TOKENbeforequarto render.
- In Apps Script:
With this setup:
- Form submissions write
Meta Created At,Meta Updated At, andMeta Source = form. - Direct sheet edits automatically update
Meta Updated AtandMeta Source = manualviaonEdit(e). - The dashboard freshness cards use these metadata columns when available.
- URL health can be tracked in
Meta URL Status,Meta URL Checked At, andMeta URL Check Detail. - Submit endpoint protections include token verification, validation, formula-injection protection, global rate limits, and short-window duplicate suppression.
This repository includes .github/workflows/url-link-check.yml to check all inventory URLs daily and write link-health metadata back to the sheet.
Required repository secrets:
GOOGLE_SERVICE_ACCOUNT_JSON: full JSON key for a Google service accountRWD_SHEET_ID: spreadsheet ID (the long ID in the sheet URL)SUBMIT_TOKEN: token injected at build-time for the submission form (must match Apps Script Script Property)
Important:
- Share the Google Sheet with the service account email as an Editor.
- The checker updates only:
Meta URL StatusMeta URL Checked AtMeta URL Check Detail
Modify index.qmd to match your data structure:
- Update column names in the data processing code
- Adjust metrics calculations
- Customize visualizations
- Add or remove sections as needed
# Start live preview with auto-reload
make previewThis will open a browser with your dashboard. The page will automatically reload when you make changes to the code.
Other useful commands:
make render- Build the site once (output to_site/)make clean- Remove generated filesmake help- See all available commands
-
Create a GitHub Repository:
# Add your remote repository git remote add origin https://github.com/YOUR_USERNAME/YOUR_REPO_NAME.git -
Enable GitHub Pages:
- Go to your repository on GitHub
- Navigate to Settings β Pages
- Under "Build and deployment", select Source: GitHub Actions
-
Push Your Code:
git add . git commit -m "Initial commit: Dashboard setup" git push -u origin main
-
Automatic Deployment:
- The GitHub Action will automatically run on push to
main - After 2-3 minutes, your dashboard will be live at:
https://YOUR_USERNAME.github.io/YOUR_REPO_NAME/
- The GitHub Action will automatically run on push to
To automatically refresh your dashboard data on a schedule:
- Open
.github/workflows/publish.yml - Uncomment the schedule section:
schedule: - cron: '0 0 * * *' # Daily at midnight UTC
- Commit and push the change
Common cron schedules:
0 0 * * *- Daily at midnight0 */6 * * *- Every 6 hours0 0 * * 1- Weekly on Mondays
rwd_wg/
βββ .github/
β βββ workflows/
β βββ publish.yml # GitHub Actions deployment workflow
βββ apps_script/
β βββ Code.gs # Google Apps Script endpoint for form submissions
βββ data/
β βββ options_template.csv # Starter options list for the Options tab
βββ _quarto.yml # Quarto project configuration
βββ index.qmd # Main dashboard page
βββ submit.qmd # Data entry form page
βββ about.qmd # About page
βββ custom.scss # Custom SCSS theming
βββ styles.css # Additional CSS styles
βββ DESCRIPTION # R package dependencies
βββ .gitignore # Git ignore rules
βββ README.md # This file
- Colors and Theme: Edit
custom.scssto change colors, fonts, and overall theme - Layout: Modify
styles.cssfor layout adjustments - Quarto Theme: Change the theme in
_quarto.yml(options: cosmo, flatly, darkly, etc.)
- Dashboard Title: Update in
_quarto.ymlandindex.qmd - Metrics: Modify the "Key Metrics" section in
index.qmd - Visualizations: Add, remove, or customize plots using ggplot2 syntax
- About Page: Edit
about.qmdwith your project information
Your Google Sheet should be structured with:
- Column headers in the first row
- One row per record
- Dates in a consistent format (recommended: YYYY-MM-DD)
Example structure (modify to match your needs):
date | metric1 | metric2 | category | status
2024-01-01 | 100 | 45 | Type A | Active
2024-01-08 | 105 | 52 | Type B | Complete
- Ensure your sheet is set to "Anyone with the link can view"
- Verify the URL is correct in
index.qmd - Check that column names match your code
- Review the GitHub Actions logs for error messages
- Check the Actions tab in your GitHub repository for error logs
- Ensure GitHub Pages is enabled in repository settings
- Verify all R packages are listed in the workflow file
- Ensure Quarto is installed:
quarto --version - Ensure R packages are installed
- Try rendering manually:
quarto render
Contributions are welcome! Feel free to:
- Report bugs
- Suggest new features
- Submit pull requests
- Improve documentation
This project is open source and available under the MIT License.
Need help? Open an issue or contact the project maintainers.