citelynq.websample/README.md

6.1 KiB

CiteLynq Web Sample

A sample ASP.NET Core web application demonstrating how to use the CiteLynq API to search for verified citations across multiple authoritative sources.

Features

ASP.NET Core 9.0 minimal API Static file hosting with wwwroot Proxy endpoints to hide API keys from client Clean, modern UI with gradient design Search across multiple data sources Display formatted citations (APA, MLA, Bluebook) Filter by source type (ArXiv, PubMed, CourtListener, etc.) Responsive design Local storage for API key persistence

Quick Start

1. Get an API Key

  1. Visit https://citelynq.com/app/api-keys
  2. Create a new API key
  3. Copy the key (starts with cl_)

2. Run the Application

cd /repos/CiteFlow/samples/CiteLynq.WebSample
dotnet run

The application will start on http://localhost:5100

3. Use the Application

  1. Open your browser to http://localhost:5100
  2. Enter your API key
  3. Enter a search query (e.g., "climate change")
  4. Click "Search"

Project Structure

CiteLynq.WebSample/
├── Program.cs                 # ASP.NET Core minimal API
├── CiteLynq.WebSample.csproj  # Project file
├── Properties/
│   └── launchSettings.json    # Launch configuration
└── wwwroot/
    └── index.html             # Single-page application

How It Works

Backend (Program.cs)

The backend provides proxy endpoints to securely call the CiteLynq API:

  1. GET /api/search - Proxies search requests

    • Accepts: query parameters (q, sourceType, page, pageSize)
    • Headers: X-API-Key
    • Returns: Search results from CiteLynq API
  2. GET /api/articles/{id} - Proxies article detail requests

    • Accepts: article ID as path parameter
    • Headers: X-API-Key
    • Returns: Article details from CiteLynq API

Why use a proxy?

  • Hides your API key from client-side code
  • Prevents CORS issues
  • Adds an abstraction layer for future enhancements
  • Enables server-side caching if needed

Frontend (wwwroot/index.html)

The frontend is a self-contained single-page application:

  • API Key Storage: Saves API key in localStorage
  • Search Interface: Query input and source filter
  • Results Display: Shows citations with metadata
  • Responsive Design: Works on desktop and mobile

API Endpoints

Search Citations

GET /api/search?q=climate%20change&sourceType=ArXiv&page=1&pageSize=20
X-API-Key: cl_your-api-key-here

Response:

{
  "data": {
    "results": [
      {
        "id": "arxiv-2301.12345",
        "sourceType": "ArXiv",
        "title": "Climate Change Research",
        "authors": ["Dr. Jane Smith"],
        "abstract": "...",
        "publishedDate": "2023-01-15",
        "url": "https://arxiv.org/abs/2301.12345",
        "citations": {
          "apa": "Smith, J. (2023)...",
          "mla": "Smith, Jane...",
          "chicago": "..."
        }
      }
    ],
    "totalCount": 145
  }
}

Get Article Details

GET /api/articles/arxiv-2301.12345
X-API-Key: cl_your-api-key-here

Configuration

Change API Base URL

Edit Program.cs line 24 to point to a different API:

const string API_BASE_URL = "https://citelynq.com/api";
// Or for local development:
// const string API_BASE_URL = "http://localhost:5000/api";

Change Port

Edit Properties/launchSettings.json:

{
  "profiles": {
    "http": {
      "applicationUrl": "http://localhost:5100"
    }
  }
}

Development

Prerequisites

  • .NET 9.0 SDK
  • Visual Studio 2022 / VS Code / Rider

Build

dotnet build

Run

dotnet run

Publish

dotnet publish -c Release -o ./publish

Customization

Add More Endpoints

Add new proxy endpoints in Program.cs:

app.MapGet("/api/sources", async (HttpContext context, IHttpClientFactory httpClientFactory) =>
{
    var apiKey = context.Request.Headers["X-API-Key"].FirstOrDefault();
    var httpClient = httpClientFactory.CreateClient();
    var httpRequest = new HttpRequestMessage(HttpMethod.Get, $"{API_BASE_URL}/sources");
    httpRequest.Headers.Add("X-API-Key", apiKey);
    var response = await httpClient.SendAsync(httpRequest);
    return Results.Content(await response.Content.ReadAsStringAsync(), "application/json");
});

Customize UI

Edit wwwroot/index.html:

/* Change color scheme */
body {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

Add Pagination

Add pagination controls in the HTML:

function displayResults(data) {
    // ... existing code ...

    if (data.totalPages > 1) {
        html += `<div class="pagination">
            <button onclick="loadPage(${data.currentPage - 1})">Previous</button>
            <span>Page ${data.currentPage} of ${data.totalPages}</span>
            <button onclick="loadPage(${data.currentPage + 1})">Next</button>
        </div>`;
    }
}

Security Notes

⚠️ Important:

  1. API Key Protection: The proxy pattern keeps API keys server-side
  2. CORS: Configured for development (allow all origins). Restrict in production.
  3. Input Validation: Always validate user input
  4. HTTPS: Use HTTPS in production environments

Troubleshooting

Port Already in Use

Change the port in Properties/launchSettings.json

CORS Errors

The application includes CORS middleware for development. For production, configure specific origins:

builder.Services.AddCors(options =>
{
    options.AddDefaultPolicy(policy =>
    {
        policy.WithOrigins("https://yourdomain.com")
              .AllowAnyMethod()
              .AllowAnyHeader();
    });
});

API Key Not Working

  1. Verify the key starts with cl_
  2. Check the key is active in your account
  3. Ensure the key has available credits

Learn More

License

This sample is provided as-is for demonstration purposes.