Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Page Embedding Feature (aka Hybrid UI)#23161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Draft
enisn wants to merge14 commits intodev
base:dev
Choose a base branch
Loading
fromhybrid-ui
Draft

Page Embedding Feature (aka Hybrid UI)#23161

enisn wants to merge14 commits intodevfromhybrid-ui

Conversation

@enisn
Copy link
Member

@enisnenisn commentedJun 23, 2025
edited
Loading

Description

Resolves#23102

This PR adds a couple of features. Here is the list and explaination:

Controlling LayoutElements via IPageLayout

@usingVolo.Abp.AspNetCore.Mvc.UI.Layout@injectIPageLayoutPageLayout@{PageLayout.RenderLayoutElements=false;}
  • It's ready for embedding:

image


Embedding Library

Introduced a new package named:Volo.Abp.AspNetCore.Mvc.UI.Embedding.

When this package added, it replaces the original PageLayout withEmbeddingPageLayout and controls layout elements according to options:

Configure<PageEmbeddingOptions>(options=>{// Automatically embed pages when accessed from iframesoptions.AlwaysEmbedIFrameRequests=true;});
Configure<PageEmbeddingOptions>(options=>{// Specific paths that should always be embeddedoptions.EmbeddedPaths.Add("/embed/dashboard");options.EmbeddedPaths.Add("/reports/widget");// Path patterns with wildcardsoptions.EmbeddedPathPatterns.Add("/api/embed/*");options.EmbeddedPathPatterns.Add("*/widget");// Customize query parameter name and valuesoptions.QueryParameterName="iframe";options.QueryParameterValues.Add("yes");// Enable automatic iframe detectionoptions.AlwaysEmbedIFrameRequests=true;});

How It Works

  1. ThePageLayout.RenderLayoutElements property is automatically set tofalse when embedding conditions are met
  2. Themes check this property to conditionally render navigation, headers, footers, etc.
  3. ThePageEmbeddingService evaluates multiple factors:
    • IFrame detection (whenAlwaysEmbedIFrameRequests = true):
      • Sec-Fetch-Dest: iframe header (most reliable)
      • Sec-Fetch-Site +Sec-Fetch-Mode headers
      • Custom headers (X-Frame-Request,X-Iframe-Request, etc.)
      • X-Requested-With header
      • Referer header analysis (least reliable)
    • Query parameters (?embed=true)
    • Configured embedded paths
    • Path patterns with wildcards

ABP Embedding Web Component (npm package)

A framework-agnostic web component for embedding iframe content with data passing capabilities.

Features

  • Framework Agnostic: Works with plain HTML, Vue, Angular, React, and any other framework
  • Auto-Height: Automatically resize iframe to match content height
  • Data Passing: Send data to iframe content using postMessage API
  • Event Handling: Listen for iframe load and message events
  • URL Synchronization: Keep parent and iframe URLs in sync with browser history support
  • Clean Styling: No borders, outlines, or visual artifacts by default
  • Responsive: Built-in responsive behavior options
  • TypeScript Ready: Includes type definitions
  • Accessible: Proper ARIA attributes and semantic HTML

Installation

npm install @abp/aspnetcore.mvc.ui.embedding

Usage

Basic HTML Usage

<!DOCTYPE html><html><head><linkrel="stylesheet"href="~/libs/abp/embedding/abp-embedding.css"></head><body><!-- Basic usage --><abp-embeddingsrc="https://example.com"width="800"height="600"></abp-embedding><!-- With responsive behavior --><abp-embeddingsrc="https://example.com"class="responsive"></abp-embedding><!-- With URL synchronization --><abp-embeddingsrc="https://example.com"width="100%"height="600px"url-sync="true"></abp-embedding><!-- With auto-height --><abp-embeddingsrc="https://example.com"width="100%"auto-height="true"></abp-embedding><scriptsrc="~/libs/abp/embedding/abp-embedding.js"></script></body></html>

Iframe Content Setup

Include this script in your iframe content to enable height communication:

<!DOCTYPE html><html><head><title>Your Iframe Content</title></head><body><!-- Your content here --><scriptsrc="path/to/abp-embedding-iframe.js"></script></body></html>

The iframe script automatically:

  • Waits for page to fully load (including images)
  • Measures content height using multiple methods
  • Sends height updates to parent via postMessage
  • Monitors for content changes (if enabled)
  • Handles configuration from parent

Auto-Height Events

// Listen for height updatesembedding.addEventListener('height-updated',(event)=>{const{ originalHeight, appliedHeight, wasConstrained}=event.detail;console.log(`Height:${originalHeight}px →${appliedHeight}px`);if(wasConstrained){console.log('Height was constrained by min/max limits');}});

Configuration Options

{minHeight:100,// Minimum iframe height (default: 100)maxHeight:10000,// Maximum iframe height (default: 90% of viewport)watchForChanges:true,// Monitor DOM changes (default: true)debounceDelay:250// Debounce delay for change detection (default: 250ms)}

URL Synchronization

The web component supports URL synchronization between the parent page and iframe content. When enabled, the component will:

  • Keep parent and iframe URLs synchronized (paths only)
  • Add?embed=1 parameter to all iframe URLs
  • Support browser back/forward navigation
  • Work seamlessly with SPAs (Angular, React, Vue, etc.)

Example URL Mapping

Parent URL:  https://parent.com/forms/2Iframe URL:  https://iframe.com/forms/2?embed=1

Enable URL Sync

<abp-embeddingsrc="https://your-spa.com"url-sync="true"width="100%"height="600px"></abp-embedding>

Iframe Implementation for URL Sync

Your iframe application needs to implement URL change notifications:

// Detect embedded modeconstisEmbedded=newURLSearchParams(window.location.search).has('embed');// Your SPA routerfunctionnavigateToPath(path){// Update your SPA contentupdateContent(path);// Notify parent if embeddedif(isEmbedded){window.parent.postMessage({type:'url-change',path:path},'*');}}// Listen for navigation commands from parentwindow.addEventListener('message',function(event){if(event.data&&event.data.type==='navigate'){// Update URL without notifying parent (to avoid loop)window.history.replaceState({},'',event.data.path+'?embed=1');// Navigate in your SPAnavigateToPath(event.data.path);}});

URL Sync Events

embedding.addEventListener('url-synced',(event)=>{const{ type, oldPath, newPath, path, url}=event.detail;if(type==='iframe-to-parent'){console.log(`URL synced from iframe:${oldPath}${newPath}`);}elseif(type==='parent-to-iframe'){console.log(`URL synced to iframe:${path}`);}});

EngincanV reacted with thumbs up emoji
Introduces a RenderLayout property to IPageLayout and PageLayout, allowing conditional rendering of the menu, toolbar, and footer in the Application layout. Updates Application.cshtml to respect this property, enabling more flexible page layouts.
Introduces the RenderLayoutElements property to IPageLayout and updates usage throughout the codebase. This allows pages to control whether navigation, toolbar, and other layout elements are rendered, providing more flexibility for special pages like error or embedded content. Documentation is updated to explain the new property and its usage.
@enisnenisn requested a review fromCopilotJune 23, 2025 13:44
Copy link
Contributor

CopilotAI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Pull Request Overview

Adds the ability to toggle the rendering of navigation, toolbar, and other surrounding layout elements in MVC Razor views via a newRenderLayoutElements flag onIPageLayout.

  • IntroducesRenderLayoutElements property onIPageLayout andPageLayout (defaulting totrue).
  • UpdatesApplication.cshtml andAccount.cshtml to checkPageLayout.RenderLayoutElements before rendering the main navbar and to adjust container width.
  • Extends documentation to cover the newRenderLayoutElements setting.

Reviewed Changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
FileDescription
modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtmlConditionally render navbar and adjustcontainerClass based on new flag
modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtmlInjectIPageLayout and wrap navbar in conditional block
framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Layout/PageLayout.csAddedRenderLayoutElements auto-property and initializer forContent
framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Layout/IPageLayout.csAddedRenderLayoutElements to interface
docs/en/framework/ui/mvc-razor-pages/page-header.mdDocumentedRenderLayoutElements usage
Comments suppressed due to low confidence (3)

framework/src/Volo.Abp.AspNetCore.Mvc.UI/Volo/Abp/AspNetCore/Mvc/UI/Layout/PageLayout.cs:9

  • No unit or integration tests were added to verify that togglingRenderLayoutElements properly hides or shows layout elements. Consider adding tests around this new behavior.
    public bool RenderLayoutElements { get; set; } = true;

docs/en/framework/ui/mvc-razor-pages/page-header.md:22

  • Duplicate wordpages in the description. It should read: "useful for public pages, error pages, or embedded content..."
* This is useful for pages public pages, error pages, or embedded content where you want a clean layout without navigation.

modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml:21

  • PageLayout is referenced here but not injected in this view. Add@inject IPageLayout PageLayout at the top ofApplication.cshtml to prevent a runtime error.
    var containerClass = ViewBag.FluidLayout == true || PageLayout.RenderLayoutElements == false ? "container-fluid" : "container"; //TODO: Better and type-safe options

Introduces the PageEmbedding feature, allowing ABP MVC pages to be embedded in other UI technologies like iframes by conditionally disabling layout elements. This includes new classes and interfaces for embedding services, options for configuration, and automatic iframe detection. Updates to the PageLayout class ensure compatibility with the new embedding logic. Documentation is added to explain usage and configuration options.
@enisnenisn changed the titleControlling layout elements rendering by IPageLayout on MVCPage Embedding Feature (aka Hybrid UI)Jun 25, 2025
Included 'Volo.Abp.AspNetCore.Mvc.UI.Embedding' in the list of projects for packaging. This ensures the Embedding module is built and packaged with the rest of the framework.
@enisnenisn requested a review fromhikalkanJune 25, 2025 08:20
Updated the CSS for the abp-embedding component to improve iframe presentation. Added important flags to various properties to ensure consistent rendering across browsers, including border, outline, background, and shadow styles. This change aims to enhance the visual integration of embedded content.
Introduces an auto-height capability to the aspnetcore.mvc.ui.embedding web component, allowing iframes to automatically resize to fit their content. Adds supporting documentation, example demos, a new iframe-side script for height measurement and communication, and updates CSS and JS to support configuration, events, and programmatic control of auto-height.
Introduced EmbeddedScriptViewComponent and its view to inject an embedding script when the page is embedded. Updated EmbeddingPageLayout to expose IsEmbedded property and set it based on the request. Registered the view component to render at the end of the body via layout hooks.
Simplifies the ABP embedding iframe script and web component by removing bidirectional messaging, URL sync, and complex height measurement strategies. The iframe now only reports its height to the parent, and the parent component updates the iframe height accordingly. CSS is updated to remove default and auto-height-related height rules, delegating all height management to JavaScript for more predictable behavior.
Introduces logic to synchronize the browser's URL fragment with the navigation state of the embedded iframe, allowing back/forward navigation and deep linking. Only one instance manages history to prevent conflicts, and cross-origin navigation is handled gracefully.
Introduces URL change monitoring in abp-embedding-iframe.js, reporting navigation events to the parent window via postMessage. Updates abp-embedding.js to handle 'url-change' messages from the iframe and dispatches a custom 'iframe-loaded' event. Also sets a minimum height for embedded iframes in abp-embedding.css to improve user experience.
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

Copilot code reviewCopilotCopilot left review comments

@hikalkanhikalkanAwaiting requested review from hikalkan

At least 1 approving review is required to merge this pull request.

Assignees

No one assigned

Projects

None yet

Milestone

backlog

Development

Successfully merging this pull request may close these issues.

ABP Hybrid UI System: Re-using module UIs in different technologies

4 participants

@enisn@hikalkan@ismcagdas

[8]ページ先頭

©2009-2025 Movatter.jp